pandasで欠損値NaNを含む行・列を抽出

Modified: | Tags: Python, pandas

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, Seriesisnull()および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.DataFrameisnull()の結果に対して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

関連カテゴリー

関連記事