NumPy配列ndarrayの欠損値np.nanを含む行や列を削除
NumPy配列ndarray
の欠損値NaN
(np.nan
)を含む行・列を削除するには、np.isnan()
で欠損値を判定し、any()
やall()
メソッドを使って欠損値が含まれていない行・列を抽出する。
PythonにおけるNaN
の扱いについての基本は以下の記事を参照。
- 関連記事: Pythonにおけるnanの判定
欠損値を削除するのではなく他の値で置き換える場合は以下の記事を参照。
本記事のサンプルコードのNumPyのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として、データが欠落したCSVファイルをnp.genfromtxt()
で読み込んで使う。欠落箇所が欠損値NaN
となる。
import numpy as np
print(np.__version__)
# 1.26.1
a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
ndarrayの欠損値NaNをすべて削除
要素が欠損値NaN
か判定する関数np.isnan()
を使って、欠損値の位置がTrue
となるndarray
を取得できる。
a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
print(np.isnan(a))
# [[False False True False]
# [False True True False]
# [False False False False]]
このndarray
に否定演算子~
を使うと欠損値NaN
の位置がFalse
になり、これをマスクとして使うと欠損値を削除(欠損値ではない要素を抽出)できる。残る要素の個数がバラバラなので元の配列ndarray
の形状は維持されず、平坦化(一次元化)される。
print(~np.isnan(a))
# [[ True True False True]
# [ True False False True]
# [ True True True True]]
print(a[~np.isnan(a)])
# [11. 12. 14. 21. 24. 31. 32. 33. 34.]
ndarrayの欠損値NaNを含む行を削除
欠損値NaN
を含む行を削除するには、ndarray
に一つでもTrue
があるとTrue
を返すany()
メソッドを使う。
引数axis=1
とすると、各行に対して一つでもTrue
があるかどうかを判定する。
a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
print(np.isnan(a))
# [[False False True False]
# [False True True False]
# [False False False False]]
print(np.isnan(a).any(axis=1))
# [ True True False]
否定演算子~
を使ってTrue
とFalse
を入れ替えると、欠損値が一つもない行がTrue
となる。
print(~np.isnan(a).any(axis=1))
# [False False True]
元のndarray
の行(一つ目の次元)に対してこのndarray
を適用することで、欠損値を含む行を削除(欠損値を含まない行を抽出)できる。
print(a[~np.isnan(a).any(axis=1), :])
# [[31. 32. 33. 34.]]
以下のように列の指定を省略してもよい。
print(a[~np.isnan(a).any(axis=1)])
# [[31. 32. 33. 34.]]
すべての要素が欠損値である行のみを削除するには、any()
ではなくall()
を使う。
引数axis=1
とすると、各行に対してすべての要素がTrue
かどうかを判定する。ここでは説明のために要素にnp.nan
を代入している。
a[1, 0] = np.nan
a[1, 3] = np.nan
print(a)
# [[11. 12. nan 14.]
# [nan nan nan nan]
# [31. 32. 33. 34.]]
print(np.isnan(a).all(axis=1))
# [False True False]
print(~np.isnan(a).all(axis=1))
# [ True False True]
print(a[~np.isnan(a).all(axis=1)])
# [[11. 12. nan 14.]
# [31. 32. 33. 34.]]
ndarrayの欠損値NaNを含む列を削除
欠損値NaN
を含む列を削除する場合も、行の場合と同様。
any()
で引数axis=0
とすると、各列に対して一つでもTrue
があるかどうかを判定する。否定演算子~
を使って、一つも欠損値がない列をTrue
とする。
a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
print(np.isnan(a))
# [[False False True False]
# [False True True False]
# [False False False False]]
print(np.isnan(a).any(axis=0))
# [False True True False]
print(~np.isnan(a).any(axis=0))
# [ True False False True]
元のndarray
の列(二つ目の次元)に対してこのndarray
を適用することで、欠損値を含む列を削除(欠損値を含まない列を抽出)できる。
print(a[:, ~np.isnan(a).any(axis=0)])
# [[11. 14.]
# [21. 24.]
# [31. 34.]]
すべての要素が欠損値である列のみを削除するには、any()
ではなくall()
を使う。ここでは説明のために要素にnp.nan
を代入している。
a[2, 2] = np.nan
print(a)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. nan 34.]]
print(np.isnan(a).all(axis=0))
# [False False True False]
print(~np.isnan(a).all(axis=0))
# [ True True False True]
print(a[:, ~np.isnan(a).all(axis=0)])
# [[11. 12. 14.]
# [21. nan 24.]
# [31. 32. 34.]]