web-dev-qa-db-ja.com

numpy配列で一意の非nan値を見つける方法は?

Numpyでnanを処理するクリーンな方法があるかどうか知りたいです。

my_array1=np.array([5,4,2,2,4,np.nan,np.nan,6])
print my_array1
#[  5.   4.   2.   2.   4.  nan  nan   6.]
print set(my_array1)
#set([nan, nan, 2.0, 4.0, 5.0, 6.0])

私はそれがせいぜい1nanの値を返すはずだと思ったでしょう。なぜ複数のnan値を返すのですか? numpy配列にある一意の非nan値の数を知りたいです。

ありがとう

12
user2015487

np.uniqueを使用して、isnanと組み合わせて一意の値を検索し、NaN値をフィルタリングできます。

In [22]:

my_array1=np.array([5,4,2,2,4,np.nan,np.nan,6])
np.unique(my_array1[~np.isnan(my_array1)])
Out[22]:
array([ 2.,  4.,  5.,  6.])

複数のNaN値を取得する理由については、NaN値を正常に比較できないためです。

In [23]:

np.nan == np.nan
Out[23]:
False

したがって、正しい比較を実行するには、isnanを使用する必要があります

setの使用:

In [24]:

set(my_array1[~np.isnan(my_array1)])
Out[24]:
{2.0, 4.0, 5.0, 6.0}

上記のいずれかでlenを呼び出して、サイズを取得できます。

In [26]:

len(np.unique(my_array1[~np.isnan(my_array1)]))
Out[26]:
4
18
EdChum

以前の回答ですでに述べたように、numpyはnanを比較できないため、nanを直接カウントすることはできません。 numpy.ma.count_masked あなたの友達です。たとえば、次のようになります。

>>> import numpy.ma as ma
>>> a = np.arange(5, dtype=float)
>>> a[2] = np.NaN
>>> a[3] = np.NaN
>>> a
array([ 0.,  1., nan, nan,  4.])
>>> a_masked = ma.masked_invalid(a)
>>> a_masked
masked_array(data=[0.0, 1.0, --, --, 4.0],
             mask=[False, False,  True,  True, False],
       fill_value=1e+20)
>>> ma.count_masked(a_masked)
2
0
ben26941

Setmで isnan() を使用してから、isnan()配列の結果を反復処理し、すべてのNaNオブジェクトを削除できます。

my_array1=np.array([5,4,2,2,4,np.nan,np.nan,6])
print my_array1
#[  5.   4.   2.   2.   4.  nan  nan   6.]
print set(my_array1)
#set([nan, nan, 2.0, 4.0, 5.0, 6.0])
for i,is_nan in enumerate(np.isnan(list(my_array1))):
    if is_nan:
        del my_array1[i]
0
ThePavolC