HOWTO · Python
ValueError: Python で Float NaN を整数に変換できません
このチュートリアルでは、ValueError: cannot convert float NaN to integer in Python を修正する方法を説明します。
このページの内容
int(value)やpandasによる整数型への変換では、欠損データの表現によく使われる浮動小数点値NaNを扱えません。ValueError: cannot convert float NaN to integerは、この変換上の問題を示すメッセージです。pandasでは、実際にはpandas.errors.IntCastingNaNErrorが発生し、無限大についても言及される場合があります。データ内でその値が何を意味するかに応じて、置き換えるか削除するかを選びましょう。
pandasのfillna()でNaNを置き換えて整数に変換する
対象の行を残す必要があり、妥当な代替値がある場合はfillna()を使います。欠損価格を0に置き換えるのは、アプリケーション上で0が有効な価格である場合に限ります。この自己完結型の例では、価格を指定した値で補完する方法、価格が欠損している行を削除する方法、NaNを置き換えてからNumPyのスカラー値を変換する方法を比較します。例の実行は確認済みで、[540, 0, 220]、[540, 220]、0が出力されます。
次の例を実行します。
import numpy as np
import pandas as pd
prices = pd.DataFrame({"item": ["A", "B", "C"], "price": [540.0, np.nan, 220.0]})
filled = prices.copy()
filled["price"] = filled["price"].fillna(0).astype(int)
remaining = prices.dropna(subset=["price"]).copy()
remaining["price"] = remaining["price"].astype(int)
scalar = int(np.nan_to_num(np.nan))
print(filled["price"].tolist())
print(remaining["price"].tolist())
print(scalar)
最初のリストでは、すべての行が残り、指定した値で補完されています。2つ目のリストでは、価格が欠損していた行が除かれています。スカラー値の変換例は、numpy.nan_to_num()がint()に渡せる数値スカラーを返すことを示しています。
pandasのdropna()でNaNを含む行を削除して整数に変換する
欠損値を含む行を結果から除外する場合はdropna()を使います。既定では、いずれかの列に欠損値がある行が削除されるため、ほかの列に有用なデータがあっても失われることがあります。上の例のようにsubset=["price"]を渡すと、変換する列だけを基準に行を削除できます。その後、欠損値を除いた列をastype(int)で変換します。レコードを残すことが分析上重要なら、削除後に何行残るか確認してください。
numpy.nan_to_num()でNaNを置き換えて整数に変換する
NumPyのデータでは、numpy.nan_to_num()は既定でNaNを0.0に置き換えます。別の値が必要ならnan引数で指定します。返されたスカラー値はint(...)で変換できます。または、配列に関数を適用してからastype(int)を使います。numpy.nan_to_num(numpy.nan)が返す値は配列ではないため、それに.astype()を呼び出さないでください。データに正または負の無限大も含まれる場合は、明示的に処理する必要があります。NaNだけを置き換えても、無限大は安全に整数へ変換できません。pandasでは、処理方法を決める前に、対象列の欠損値と有限でない値の両方を確認しましょう。