pandasで欠損値NaNを削除(除外)するdropna
pandas.DataFrame
, Series
の欠損値NaN
を削除(除外)するにはdropna()
メソッドを使う。
- pandas.DataFrame.dropna — pandas 2.0.3 documentation
- pandas.Series.dropna — pandas 2.0.3 documentation
欠損値NaN
の抽出・置換・カウントについては以下の記事を参照。
- 関連記事: pandasで欠損値NaNを含む行・列を抽出
- 関連記事: pandasで欠損値NaNを置換(穴埋め)するfillna
- 関連記事: pandasで欠損値NaNが含まれているか判定、個数をカウント
なお、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である行・列を削除: how='all'
dropna()
の引数how
を'all'
とすると、すべての値が欠損値の行が削除される。
print(df.dropna(how='all'))
# name age state point other
# 0 Alice 24.0 NY 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
引数axis
を1
または'columns'
とすると、すべての値が欠損値の列が削除される。
print(df.dropna(how='all', axis=1))
# name age state point
# 0 Alice 24.0 NY NaN
# 1 NaN NaN NaN 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
引数axis
を0
または'index'
とすると行が削除される。デフォルトがaxis=0
なので、省略した場合は最初の例のように行が削除される。
以前はaxis=[0, 1]
とすると行と列がどちらも削除されたが、バージョン1.0.0
からリストやタプルでの指定はサポートされなくなった。行・列両方を削除したい場合はdropna()
を繰り返し適用すればよい。
# print(df.dropna(how='all', axis=[0, 1]))
# TypeError: supplying multiple axes to axis is no longer supported.
print(df.dropna(how='all').dropna(how='all', axis=1))
# 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
欠損値NaNが一つでも含まれる行・列を削除: how='any'(デフォルト)
すべての値が欠損値である行と列を削除したデータを例とする。
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
dropna()
の引数how
を'any'
とすると、欠損値が一つでも含まれる行が削除される。デフォルトがhow='any'
なので、何も指定しないとこの動作になる。
print(df2.dropna(how='any'))
# name age state point
# 3 Dave 68.0 TX 70.0
print(df2.dropna())
# name age state point
# 3 Dave 68.0 TX 70.0
引数axis
を1
または'columns'
とすると、列に適用。欠損値が一つでも含まれる列が削除される。
print(df2.dropna(axis=1))
# name
# 0 Alice
# 2 Charlie
# 3 Dave
# 4 Ellen
# 5 Frank
欠損値NaNではない要素の数に応じて行・列を削除: thresh
dropna()
の引数thresh
に個数を指定すると、欠損値ではない要素の数に応じて行・列を削除できる。
例えばthresh=3
とすると、欠損値ではない要素の数が3個以上含まれている行が残り、それ以外の行(欠損値ではない要素の数が3個未満の行)が削除される。
print(df.dropna(thresh=3))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen NaN CA 88.0 NaN
引数axis
を1
または'columns'
とすると、列に適用。
print(df.dropna(thresh=3, axis=1))
# name age state
# 0 Alice 24.0 NY
# 1 NaN NaN NaN
# 2 Charlie NaN CA
# 3 Dave 68.0 TX
# 4 Ellen NaN CA
# 5 Frank 30.0 NaN
特定の行・列に欠損値NaNがある列・行を削除: subset
特定の行・列を基準に削除したい場合は、dropna()
の引数subset
に対象としたい行名・列名(行ラベル・列ラベル)をリストで指定する。対象が一つでもsubset=['name']
のようにリストで指定する必要がある。
デフォルトはhow='any'
, axis=0
なので、subset
で指定した列に欠損値がある行が削除される。
print(df.dropna(subset=['age']))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 5 Frank 30.0 NaN NaN NaN
print(df.dropna(subset=['age', 'state']))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
引数how
を'all'
とすると、指定した列すべてが欠損値である行が削除される。
print(df.dropna(subset=['age', 'state'], how='all'))
# name age state point other
# 0 Alice 24.0 NY 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
引数axis
を1
または'columns'
とすると、subset
で指定した行に欠損値がある列が削除される。引数how
も同時に指定可能。
print(df.dropna(subset=[0, 4], axis=1))
# name state
# 0 Alice NY
# 1 NaN NaN
# 2 Charlie CA
# 3 Dave TX
# 4 Ellen CA
# 5 Frank NaN
print(df.dropna(subset=[0, 4], axis=1, how='all'))
# name age state point
# 0 Alice 24.0 NY NaN
# 1 NaN NaN NaN 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
存在しない行名・列名を指定するとエラー。axis=1
としたのに列名を指定した場合などもエラーになる。
# print(df.dropna(subset=['age', 'state', 'xxx']))
# KeyError: ['xxx']
# print(df.dropna(subset=['age', 'state'], axis=1))
# KeyError: ['age', 'state']
元のオブジェクトを変更: inplace
これまでの例のように、デフォルトでは新しいオブジェクトを返して元のオブジェクトは変更されないが、引数inplace=True
とすると元のオブジェクト自体が変更される。
df.dropna(subset=['age'], inplace=True)
print(df)
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 5 Frank 30.0 NaN NaN NaN
pandas.Seriesの場合
pandas.Series
のdropna()
メソッドの有効な引数はinplace
のみ。一次元データなので単純に欠損値の要素が削除されるだけ。
s = pd.read_csv('data/src/sample_pandas_normal_nan.csv')['age']
print(s)
# 0 24.0
# 1 NaN
# 2 NaN
# 3 68.0
# 4 NaN
# 5 30.0
# Name: age, dtype: float64
print(s.dropna())
# 0 24.0
# 3 68.0
# 5 30.0
# Name: age, dtype: float64
s.dropna(inplace=True)
print(s)
# 0 24.0
# 3 68.0
# 5 30.0
# Name: age, dtype: float64