Python で解析 15
“Advent Calendar 2013 - Python で解析!” の十五日目。DataFrame - 10
1. データの準備
今回は、fillna を使ってみる。いつも綺麗なデータなら良いのだが、欠損しているデータをどうにかしなきゃならないシチュエーションだ。
In [1]: import pandas as pd In [2]: df1 = pd.DataFrame({ ...: u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'], ...: u'性別': [u'男', u'男', u'女', u'女'] , ...: u'身長': [181, 173, 159, 164], ...: u'体重': [79, 71, 51, 52] ...: }, index=['3B005', '3B003', '3B002', '3B001']) In [3]: df2 = pd.DataFrame({ ...: u'誕生日': ['1981/01/01', '1982/02/02', '1983/03/03', '1984/04/04'] ...: }, index=['3B004','3B005','3B003', '3B002']) In [4]: df3 = pd.DataFrame({ ...: u'好きなもの': [u'りんご', u'ばなな', u'いちご', u'メロン'], ...: }, index=['3B004','3B005','3B003', '3B001']) In [5]: df = df1.join([df2, df3]) In [6]: df Out[6]: 体重 名前 性別 身長 誕生日 好きなもの 3B005 79 山田 男 181 1982/02/02 ばなな 3B003 71 鈴木 男 173 1983/03/03 いちご 3B002 51 佐藤 女 159 1984/04/04 NaN 3B001 52 木村 女 164 NaN メロン
今回は nan を作るために、join している。
2. nan の数も合わせて算出したい
例えば、データの個数を数えてみると nan の数が分からない。
In [7]: df[u'好きなもの'].value_counts() Out[7]: ばなな 1 メロン 1 いちご 1 dtype: int64
好きなものがわからない数も把握したので、nan のところに '不明' と入れてみることにする。
In [8]: df.fillna(u'不明') Out[8]: 体重 名前 性別 身長 誕生日 好きなもの 3B005 79 山田 男 181 1982/02/02 ばなな 3B003 71 鈴木 男 173 1983/03/03 いちご 3B002 51 佐藤 女 159 1984/04/04 不明 3B001 52 木村 女 164 不明 メロン
誕生日の欄も不明が入った。これでもかまわないのだが、カラムを限定することもできる。
In [9]: df.fillna({u'好きなもの': u'不明'}) Out[9]: 体重 名前 性別 身長 誕生日 好きなもの 3B005 79 山田 男 181 1982/02/02 ばなな 3B003 71 鈴木 男 173 1983/03/03 いちご 3B002 51 佐藤 女 159 1984/04/04 不明 3B001 52 木村 女 164 NaN メロン
今度は、好きなもののカラムだけが変更された。この状態で、もう一度、データの個数を数えてみる。
In [10]: df[u'好きなもの'].value_counts() Out[10]: ばなな 1 メロン 1 いちご 1 dtype: int64
ん? 最初と同じ結果になってしまった。
3. 元の DataFrame に反映したい
実は、次のようにすれば不明分もカウントされる。
In [11]: df[u'好きなもの'].fillna(u'不明').value_counts() Out[11]: ばなな 1 不明 1 メロン 1 いちご 1 dtype: int64
fillna が新しいオブジェクトを返すので、元の DataFrame に '不明' が反映されなかったのが、先ほどの失敗の原因だ。
次のようにすると、元の DataFrame に反映される。
In [12]: df[u'好きなもの'] = df[u'好きなもの'].fillna(u'不明') In [13]: df Out[13]: 体重 名前 性別 身長 誕生日 好きなもの 3B005 79 山田 男 181 1982/02/02 ばなな 3B003 71 鈴木 男 173 1983/03/03 いちご 3B002 51 佐藤 女 159 1984/04/04 不明 3B001 52 木村 女 164 NaN メロン
あるいは df を入れ替えてしまってもいい。
In [14]: df = df.fillna({u'好きなもの': u'不明'}) In [15]: df Out[15]: 体重 名前 性別 身長 誕生日 好きなもの 3B005 79 山田 男 181 1982/02/02 ばなな 3B003 71 鈴木 男 173 1983/03/03 いちご 3B002 51 佐藤 女 159 1984/04/04 不明 3B001 52 木村 女 164 NaN メロン
今度は、不明分もカウントされるハズだ。
In [16]: df[u'好きなもの'].value_counts() Out[16]: ばなな 1 不明 1 メロン 1 いちご 1 dtype: int64
今回はこんなところで。