「ValueError: Input contains NaN, infinity or a value too large for dtype('float64').」

Pythonで「scikit-learn」ライブラリを使用しているとき、「ValueError: Input contains NaN, infinity or a value too large for dtype('float64').」というエラーが発生することがある。データに「NaN」(非数値)、「inf」(無限大)、「-inf」(負の無限大)が含まれていると起こる。

エラーをなくすためには有効な数値に置き換える。ここでは例として「NaN」、「inf」、「-inf」を含むNumpy配列とPandasシリーズを作成し、これらを「0」で置き換えてみる。

○以下のサンプルプログラムをSpyderの「IPython console」にコピー&ペーストして「Enter」キーを2回押す

import numpy as np
import pandas as pd

a = np.array([float('nan'), float('inf'), float('-inf')])
s = pd.Series(np.array([float('nan'), float('inf'), float('-inf')]))

print(a)
a[(np.isnan(a)) | (a==float("inf")) | (a==float("-inf"))] = 0.0
print(a)

print('\n')

print(s)
s[(np.isnan(s)) | (s==float("inf")) | (s==float("-inf"))] = 0.0
print(s)

出力

[ nan  inf -inf]
[ 0.  0.  0.]

0    NaN
1    inf
2   -inf
dtype: float64
0    0.0
1    0.0
2    0.0
dtype: float64

たまたま気付いたことがある。Numpy配列を作成した後、これをPandasシリーズに変換して別の変数としたとする。Numpy配列のデータを何かに置き換えると、別の変数であるはずのPandasシリーズのデータも置き換えられてしまう。これは注意しないと予想外の問題を起こす可能性がある。

○以下のサンプルプログラムをSpyderの「IPython console」にコピー&ペーストして「Enter」キーを2回押す

import numpy as np
import pandas as pd

a = np.array([float('nan'), float('inf'), float('-inf')])
s = pd.Series(a)

print(s)
a[(np.isnan(a)) | (a==float("inf")) | (a==float("-inf"))] = 0.0
print(s)

出力

0    NaN
1    inf
2   -inf
dtype: float64
0    0.0
1    0.0
2    0.0
dtype: float64
(2017/02/04更新)