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