HOWTO · NumPy

NumPy 配列から NaN 値を削除する

Python で NumPy 配列から NaN 値を削除する方法を解説します

このページの内容

NumPy 配列から NaN 要素を取り除くには、NaN ではない値を示すマスクを作り、そのマスクで要素を選択します。NumPy 配列では array[~np.isnan(array)] と書くのが簡潔です。

NumPy の logical_not() と isnan() 関数で NaN 値を削除する

np.isnan(array) は、要素が NaN の位置で True になるブール配列を返します。np.logical_not() はその値を反転するため、通常の数値に対して True となるマスクが得られます。ブールインデックスを使うと、条件に合う要素が元の順序のまま選択されます。この NumPy のブール配列では、~ 演算子を使うと同じ処理を短く書けます。

次の例では、2通りの書き方に加え、入力がすべて NaN の場合と NaN を含まない場合の結果も確認できます。

import numpy as np

values = np.array([1.0, np.nan, 3.0])
without_nan = values[np.logical_not(np.isnan(values))]
without_nan_short = values[~np.isnan(values)]
all_nan = np.array([np.nan, np.nan])
no_nan = np.array([1, 2, 3])
print(without_nan)
print(without_nan_short)
print(all_nan[~np.isnan(all_nan)])
print(no_nan[~np.isnan(no_nan)])
[1. 3.]
[1. 3.]
[]
[1 2 3]

2つのマスクで得られる値は同じです。すべて NaN の入力では要素のない配列になり、NaN を含まない入力はそのまま返ります。詳しくは、公式ドキュメントの np.logical_not()とnp.isnan()を参照してください。

NumPy の isfinite() 関数で NaN 値を削除する

np.isfinite(array) は、有限値に対して True となるマスクを作ります。このマスクでインデックスを指定すると NaN は除かれますが、正の無限大と負の無限大も除かれます。有限値だけを残したい場合に使ってください。無限大を残して NaN だけを取り除くには、上で示した np.isnan() の反転マスクを使います。数値型ごとの動作については、np.isfinite() の公式ドキュメントを参照してください。

math.isnan() で NaN 値を削除する

Python 標準ライブラリの math.isnan() は、1つのスカラー値を調べる関数です。まず import math で読み込みます。1次元の数値配列なら、リスト内包表記でブールマスクを作れます。たとえば keep = [not math.isnan(value) for value in values] とし、その後 filtered = values[keep] とします。この方法は Python 上で配列の各要素を順に処理しますが、NumPy の関数は配列全体に対して処理します。この例は1次元入力を前提としています。多次元配列を反復すると、スカラー値ではなく部分配列が得られるためです。

pandas.isnull() で NaN 値を削除する

プロジェクトですでに pandas を使っている場合は、import pandas as pd で読み込み、pd.isnull() で欠損値を判定して反転マスクを作れます。例: filtered = values[~pd.isnull(values)]。これは pandas の関数であり、NumPy のメソッドではありません。この処理だけのために pandas を新たにインストールする必要はありません。対応するデータ構造にほかの pandas の欠損値表現が含まれている場合も、それらを検出します。詳しくは既存の pandas isnull() リファレンスを参照してください。