85

私の単体テストでは、2つの配列が同一であるかどうかを確認したいと思います。縮小例:

a = np.array([1, 2, np.NaN])
b = np.array([1, 2, np.NaN])

if np.all(a==b):
    print 'arrays are equal'

これは機能しませんnan != nan。続行するための最良の方法は何ですか?

4

10 に答える 10

50

1.19より前のバージョンのnumpyの場合、これは、単体テストを特に含まない状況でおそらく最良のアプローチです。

>>> ((a == b) | (numpy.isnan(a) & numpy.isnan(b))).all()
True

ただし、最新バージョンでは、array_equal関数に新しいキーワード引数、が提供さequal_nanれます。これは、法案に正確に適合します。

これはflyingdutchmanによって最初に指摘されました。詳細については、以下の彼の回答を参照してください。

于 2012-05-22T21:24:50.127 に答える
47

numpy.testing.assert_equalまたはnumpy.testing.assert_array_equaltry/except:を使用することもできます。

In : import numpy as np

In : def nan_equal(a,b):
...:     try:
...:         np.testing.assert_equal(a,b)
...:     except AssertionError:
...:         return False
...:     return True

In : a=np.array([1, 2, np.NaN])

In : b=np.array([1, 2, np.NaN])

In : nan_equal(a,b)
Out: True

In : a=np.array([1, 2, np.NaN])

In : b=np.array([3, 2, np.NaN])

In : nan_equal(a,b)
Out: False

編集

assertこれを単体テストに使用しているので、 (取得するためにラップするのではなく)ベアのTrue/False方が自然かもしれません。

于 2012-05-22T21:42:36.257 に答える
43

最も簡単な方法は、numpy.allclose()メソッドを使用することです。これにより、nan値を持つ場合の動作を指定できます。次に、例は次のようになります。

a = np.array([1, 2, np.nan])
b = np.array([1, 2, np.nan])

if np.allclose(a, b, equal_nan=True):
    print('arrays are equal')

その後arrays are equal、印刷されます。

ここで関連ドキュメントを見つけることができます

于 2017-08-14T13:05:21.487 に答える
9

numpyでマスクされた配列を使用し、NaN値をマスクしてから、numpy.ma.allまたはnumpy.ma.allclose:を使用できます。

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.all.html

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.allclose.html

例えば:

a=np.array([1, 2, np.NaN])
b=np.array([1, 2, np.NaN])
np.ma.all(np.ma.masked_invalid(a) == np.ma.masked_invalid(b)) #True
于 2012-05-22T21:23:25.867 に答える
8

@Luis Albert Centenoの答えを完成させるために、次を使用することもできます。

np.allclose(a, b, rtol=0, atol=0, equal_nan=True)

rtolatol同等性テストの許容範囲を制御します。つまり、次のようになりallclose()ます。

all(abs(a - b) <= atol + rtol * abs(b))

デフォルトでは0に設定されていないため、True数値が近いが完全に等しくない場合、関数は戻る可能性があります。


PS:「2つの配列が同一であるかどうかを確認したい」>>実際、あなたは同一性ではなく平等を探しています。Pythonでは同じではないので、同じレキシコンを共有するためには、誰もが違いを理解する方が良いと思います。(https://www.blog.pythonlibrary.org/2017/02/28/python-101-equality-vs-identity/

あなたはキーワードを介してアイデンティティをテストしますis

a is b
于 2019-11-05T10:13:57.273 に答える
8

numpy関数array_equalは、質問の要件に完全に適合します。これが尋ねられたとき、それはおそらく存在していませんでした。例は次のようになります。

a = np.array([1, 2, np.NaN])
b = np.array([1, 2, np.NaN])
assert np.array_equal(a, b, equal_nan=True)

ただし、要素がdtypeの場合、これは機能しないという問題に注意してくださいobject。これがバグかどうかわからない。

于 2020-12-09T14:57:19.710 に答える
7

上記の答えを使用したとき:

 ((a == b) | (numpy.isnan(a) & numpy.isnan(b))).all()

文字列のリストを評価するときに、いくつかのエラーが発生しました。

これはより一般的なタイプです:

def EQUAL(a,b):
    return ((a == b) | ((a != a) & (b != b)))
于 2016-10-10T12:07:42.460 に答える
1

v1.9以降、numpyのarray_equal関数はequal_nan引数をサポートしています。

assert np.array_equal(a, b, equal_nan=True)
于 2021-03-24T22:58:20.090 に答える
0

単体テストなどでこれを行う場合、すべてのタイプでパフォーマンスと「正しい」動作をあまり気にしない場合は、これを使用して、数値だけでなく、すべてのタイプの配列で機能するものを作成できます。

a = np.array(['a', 'b', None])
b = np.array(['a', 'b', None])
assert list(a) == list(b)

ndarraysをlistsにキャストすると、テストで必要な動作を取得するのに役立つ場合があります。(ただし、これを本番コードやより大きな配列では使用しないでください!)

于 2019-01-16T23:08:38.707 に答える
0

私にとってこれはうまくいきました:

a = numpy.array(float('nan'), 1, 2)
b = numpy.array(2, float('nan'), 2)
numpy.equal(a, b, where = 
    numpy.logical_not(numpy.logical_or(
        numpy.isnan(a), 
        numpy.isnan(b)
    ))
).all()

PS。nanがある場合は比較を無視します

于 2021-05-02T22:47:08.570 に答える