簡単な欠損値の確かめ方
とりあえず各列に欠損値があるかどうかを知りたい、というときは
isnull
関数と
any
関数の組み合わせと
notnull
関数と
all
関数の組み合わせがあります。
前者の組み合わせのときは欠損値のある列に
True
が返され、後者の組み合わせのときは欠損値のある列に
False
が返されます。
以下のように確かめることができます。
In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: data = np.random.randn(5,5)
In [4]: data[1,3] = np.nan # 欠損値を入れる
In [5]: data[2,0] = np.nan # 欠損値2つ目
In [6]: data
Out[6]:
array([[ 2.10851627, 1.07282648, -0.97971334, 0.02266813, -0.38525149],
[-0.48737955, 0.11157585, -0.76305474, nan, -0.07192401],
[ nan, -0.97189693, -0.31556478, 0.33463695, 0.70125536],
[-0.07861912, -0.19900086, -0.01112946, 0.56708296, 0.46685101],
[-0.63178651, 1.65860916, -0.36124422, -0.00691114, -0.73076744]])
In [7]: df = pd.DataFrame(data, columns=['A','B','C','D','E']) # DataFrameの作成
...:
In [8]: df
Out[8]:
A B C D E
0 2.108516 1.072826 -0.979713 0.022668 -0.385251
1 -0.487380 0.111576 -0.763055 NaN -0.071924
2 NaN -0.971897 -0.315565 0.334637 0.701255
3 -0.078619 -0.199001 -0.011129 0.567083 0.466851
4 -0.631787 1.658609 -0.361244 -0.006911 -0.730767
In [9]: df.isnull().any()
Out[9]:
A True
B False
C False
D True
E False
dtype: bool
In [10]: df.notnull().all()
Out[10]:
A False
B True
C True
D False
E True
dtype: bool
欠損値を削除する方法
では、欠損値の削除の仕方を確認してみましょう。
欠損値を削除するにはdropna
関数を使います。読んで字のごとく、NaN値(欠損値)をドロップ(除外)します。
1つ注意ですが、inplace=True
にしないと、元のデータに変更は反映されないので注意しましょう。
以下のデータを使います。
In [11]: df = pd.Series([1, 2, 3, np.nan, 0, None], index=['A','B','C','D','E','F']) # 欠損値を含むデータを作成
In [12]: df
Out[12]:
A 1.0
B 2.0
C 3.0
D NaN
E 0.0
F NaN
dtype: float64
In [14]: df_2 = pd.DataFrame({'A':[0, 1, np.nan, 2],'B':[np.nan,2, 3, 4]})
In [15]: df_2
Out[15]:
0 0.0 NaN
1 1.0 2.0
2 NaN 3.0
3 2.0 4.0
In [16]: df_2.dropna() # 0,2行目が削除される
Out[16]:
1 1.0 2.0
3 2.0 4.0
In [17]: df = pd.DataFrame({'A': [1, np.nan, 2, np.nan, 2, np.nan],
...: 'B': [np.nan, np.nan, 3, 4, 5, 6]})
...:
In [18]: df
Out[18]:
0 1.0 NaN
1 NaN NaN
2 2.0 3.0
3 NaN 4.0
4 2.0 5.0
5 NaN 6.0
In [19]: df.dropna(how='all') # 両方とも欠損値の1行目だけが消去される
Out[19]:
0 1.0 NaN
2 2.0 3.0
3 NaN 4.0
4 2.0 5.0
5 NaN 6.0
thresh
で行あたりにいくつ以上のデータが非欠損値であれば削除しないかを指定できます。
例えば、2個以上非欠損値があればその行を残したいときはthresh=2
のように設定します。
In [28]: df = pd.DataFrame({'A':[0, np.nan, np.nan, 2, 3, 4],
...: 'B':[np.nan, np.nan, 2, 3, 5, 6],
...: 'C':[1, np.nan, np.nan, 3,5,np.nan]})
...:
In [29]: df
Out[29]:
A B C
0 0.0 NaN 1.0
1 NaN NaN NaN
2 NaN 2.0 NaN
3 2.0 3.0 3.0
4 3.0 5.0 5.0
5 4.0 6.0 NaN
In [30]: df.dropna(thresh=2) # 欠損値でないところが2つ以上残っていれば削除しない
Out[30]:
A B C
0 0.0 NaN 1.0
3 2.0 3.0 3.0
4 3.0 5.0 5.0
5 4.0 6.0 NaN
A 0.0 NaN NaN 2.0 3.0 4.0
B NaN NaN 2.0 3.0 5.0 6.0
C 1.0 NaN NaN 3.0 5.0 NaN
In [35]: df_t.dropna(axis='columns')
Out[35]:
A 2.0 3.0
B 3.0 5.0
C 3.0 5.0
5 4.0 6.0 NaN
In [41]: df.fillna({'A':-10, 'B': 0, 'C': 999}) # 列ごとに穴埋めする値を変える
Out[41]:
A B C
0 0.0 0.0 1.0
1 -10.0 0.0 999.0
2 -10.0 2.0 999.0
3 2.0 3.0 3.0
4 3.0 5.0 5.0
5 4.0 6.0 999.0
欠損値の前後を使って穴埋めをすることができます。method='ffill'
で直前の値が穴埋めの値に使われます。
ffillはforward fillの略称なので前方方向に向けて穴埋めするというイメージを持つとわかりやすいと思います。
一方、method='bfill'
はbackward fillの略称となり後方方向に向けて穴埋めするということになります。
In [42]: df_method = df.copy()
In [43]: df_method.iloc[3:,1] = np.nan
In [44]: df_method
Out[44]:
A B C
0 0.0 NaN 1.0
1 NaN NaN NaN
2 NaN 2.0 NaN
3 2.0 NaN 3.0
4 3.0 NaN 5.0
5 4.0 NaN NaN
In [45]: df_method.fillna(method='ffill') # 直前の値を使って埋めていく
Out[45]:
A B C
0 0.0 NaN 1.0
1 0.0 NaN 1.0
2 0.0 2.0 1.0
3 2.0 2.0 3.0
4 3.0 2.0 5.0
5 4.0 2.0 5.0
In [46]: df_method.fillna(method='bfill') # 直後の値を使って穴埋めをする
Out[46]:
A B C
0 0.0 2.0 1.0
1 2.0 2.0 3.0
2 2.0 2.0 3.0
3 2.0 NaN 3.0
4 3.0 NaN 5.0
5 4.0 NaN NaN
limit
引数で値を指定することで連続した欠損値で何個まで穴埋めするかを指定できます。limit
引数はmethod
が指定されているときのみ有効となります。
ではmethod='ffill'
でlimit
を変更して見ます。
In [49]: df_method.fillna(method='ffill', limit=2) # 2個連続まで
Out[49]:
A B C
0 0.0 NaN 1.0
1 0.0 NaN 1.0
2 0.0 2.0 1.0
3 2.0 2.0 3.0
4 3.0 2.0 5.0
5 4.0 NaN 5.0
In [50]: df_method.fillna(method='ffill', limit=1) # 1個連続まで
Out[50]:
A B C
0 0.0 NaN 1.0
1 0.0 NaN 1.0
2 NaN 2.0 NaN
3 2.0 2.0 3.0
4 3.0 NaN 5.0
5 4.0 NaN 5.0
In [70]: fill_df = pd.DataFrame(np.arange(18).reshape(6,3),
...: columns=['A','B','C'])
...:
In [71]: df.fillna(fill_df)
Out[71]:
A B C
0 0.0 1.0 1.0
1 3.0 4.0 5.0
2 6.0 2.0 8.0
3 2.0 3.0 3.0
4 3.0 5.0 5.0
5 4.0 6.0 17.0
今回は欠損値を削除する方法と穴埋めする方法について解説しました。
欠損値を削除する場合はdropna
、穴埋めする場合はfillna
関数を使えば大抵の欠損値処理を行うことができます。
欠損値処理を確実にこなしておくと、次のデータ処理の段階でエラーが起きにくくなるのでしっかり把握しておくと良いでしょう。
Python for Data Analysis 2nd edition –Wes McKinney(書籍)
pandas.DataFrame.dropna - pandas 0.23.4 documentation
pandas.DataFrame.fillna - pandas 0.23.4 documentation