web-dev-qa-db-ja.com

Numpy isnan()はfloatの配列で失敗します(pandasデータフレーム適用から)

pandasデータフレームへの適用から出てくるfloat(いくつかの通常の数値、いくつかのnan)の配列があります。

何らかの理由で、この配列ではnumpy.isnanが失敗しますが、以下に示すように、各要素はfloatで、numpy.isnanは各要素で正しく実行され、変数の型は間違いなくnumpy配列です。

どうしたの?!

set([type(x) for x in tester])
Out[59]: {float}

tester
Out[60]: 
array([-0.7000000000000001, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan], dtype=object)

set([type(x) for x in tester])
Out[61]: {float}

np.isnan(tester)
Traceback (most recent call last):

File "<ipython-input-62-e3638605b43c>", line 1, in <module>
np.isnan(tester)

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

set([np.isnan(x) for x in tester])
Out[65]: {False, True}

type(tester)
Out[66]: numpy.ndarray
55
tim654321

np.isnanは、ネイティブdtypeのNumPy配列(np.float64など)に適用できます。

In [99]: np.isnan(np.array([np.nan, 0], dtype=np.float64))
Out[99]: array([ True, False], dtype=bool)

オブジェクト配列に適用するとTypeErrorが発生します:

In [96]: np.isnan(np.array([np.nan, 0], dtype=object))
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

パンダがあるので、代わりに pd.isnull を使用できます-オブジェクトのNumPy配列またはネイティブdtypeを受け入れることができます:

In [97]: pd.isnull(np.array([np.nan, 0], dtype=float))
Out[97]: array([ True, False], dtype=bool)

In [98]: pd.isnull(np.array([np.nan, 0], dtype=object))
Out[98]: array([ True, False], dtype=bool)

Noneは、オブジェクト配列でもNULL値と見なされることに注意してください。

81
unutbu

@unubtuの答えに加えて、pandas numpyオブジェクト配列をネイティブ(float64)型に強制することができます。

import pandas as pd
pd.to_numeric(df['tester'], errors='coerce')

Errors = 'coerce'を指定すると、数値に解析できない文字列を強制的にNaNにできます。列タイプはdtype: float64になり、isnanチェックが機能するはずです

6

Np.isnan()およびpd.isnull()の優れた代替は

for i in range(0,a.shape[0]):
    if(a[i]!=a[i]):
       //do something here
       //a[i] is nan

nanのみがそれ自体に等しくないためです。

5
Statham