pandasで欠損値NaNを含む行・列を抽出
pandas.DataFrame
の欠損値NaN
を含む行・列を抽出するには、要素が欠損値NaN
かを判定するisnull()
またはisna()
メソッドを利用する。
欠損値ではない行・列を抽出する、すなわち、欠損値を含む行・列を削除するにはdropna()
メソッドを使う。
なお、pandasではNaN
(Not a Number: 非数)のほか、None
も欠損値として扱われる。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として、空白を含むCSVファイルを読み込んで使用する。
import pandas as pd
print(pd.__version__)
# 2.0.3
df = pd.read_csv('data/src/sample_pandas_normal_nan.csv')
print(df)
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 NaN NaN NaN NaN NaN
# 2 Charlie NaN CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen NaN CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
特定の行・列に欠損値NaNがある列・行を抽出
pandas.DataFrame
, Series
のisnull()
およびisna()
で、要素が欠損値NaN
かどうかを判定できる。
print(df.isnull())
# name age state point other
# 0 False False False True True
# 1 True True True True True
# 2 False True False True True
# 3 False False False False True
# 4 False True False False True
# 5 False False True True True
isnull()
はisna()
のエイリアスで使い方はどちらも同じ。本記事では主にisnull()
を用いるが、isna()
に置き換えてもよい。
特定の列に欠損値が含まれている行を抽出したい場合、その列のisnull()
(またはisna()
)の結果のpandas.Series
を用いてブーリアンインデックス参照で抽出する。
print(df['point'].isnull())
# 0 True
# 1 True
# 2 True
# 3 False
# 4 False
# 5 True
# Name: point, dtype: bool
print(df[df['point'].isnull()])
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 NaN NaN NaN NaN NaN
# 2 Charlie NaN CA NaN NaN
# 5 Frank 30.0 NaN NaN NaN
特定の行に欠損値が含まれている列を選択する場合も考え方は同じ。行名(行ラベル)で選択する場合はloc[]
、位置(インデックス)で選択する場合はiloc[]
を使う。
print(df.iloc[2].isnull())
# name False
# age True
# state False
# point True
# other True
# Name: 2, dtype: bool
print(df.loc[:, df.iloc[2].isnull()])
# age point other
# 0 24.0 NaN NaN
# 1 NaN NaN NaN
# 2 NaN NaN NaN
# 3 68.0 70.0 NaN
# 4 NaN 88.0 NaN
# 5 30.0 NaN NaN
欠損値NaNが一つでも含まれる行・列を抽出
特定の行・列に対する判定ではなく、欠損値が一つでも含まれる行・列を抽出する場合。
すべての値が欠損値である行と列を削除したデータを例とする。
df2 = df.dropna(how='all').dropna(how='all', axis=1)
print(df2)
# name age state point
# 0 Alice 24.0 NY NaN
# 2 Charlie NaN CA NaN
# 3 Dave 68.0 TX 70.0
# 4 Ellen NaN CA 88.0
# 5 Frank 30.0 NaN NaN
行・列ごとにTrue
がひとつでもあればTrue
と判定するany()
メソッドを使う。デフォルトは列に対する処理で、引数axis=1
とすると行に対する処理となる。
pandas.DataFrame
のisnull()
の結果に対してany()
メソッドを適用し、これを元のpandas.DataFrame
のブーリアンインデックス参照で抽出する。
一つでも欠損値NaN
を含む行を抽出する場合。
print(df2.isnull())
# name age state point
# 0 False False False True
# 2 False True False True
# 3 False False False False
# 4 False True False False
# 5 False False True True
print(df2.isnull().any(axis=1))
# 0 True
# 2 True
# 3 False
# 4 True
# 5 True
# dtype: bool
print(df2[df2.isnull().any(axis=1)])
# name age state point
# 0 Alice 24.0 NY NaN
# 2 Charlie NaN CA NaN
# 4 Ellen NaN CA 88.0
# 5 Frank 30.0 NaN NaN
一つでも欠損値NaN
を含む列を抽出する場合も同様。
print(df2.isnull().any())
# name False
# age True
# state True
# point True
# dtype: bool
print(df2.loc[:, df2.isnull().any()])
# age state point
# 0 24.0 NY NaN
# 2 NaN CA NaN
# 3 68.0 TX 70.0
# 4 NaN CA 88.0
# 5 30.0 NaN NaN