このエントリーをはてなブックマークに追加

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

今回はこんなところで。