2つのNumPy配列を要素ごとに比較して比較する


252

2つのNumPy配列の等価性を比較する最も簡単な方法は何ですか(等価性は次のように定義されています:A =すべてのインデックスのB iff i:)A[i] == B[i]

単純に使用==するとブール配列が得られます:

 >>> numpy.array([1,1,1]) == numpy.array([1,1,1])

array([ True,  True,  True], dtype=bool)

私がしなければならないのand配列が同じである、または比較する簡単な方法があるかどうかを決定するために、この配列の要素?

回答:


379
(A==B).all()

配列(A == B)のすべての値がTrueかどうかをテストします。

注:次のように、AとBの形状もテストしたい場合があります。 A.shape == B.shape

特別なケースと代替案(dbauppの回答とyoavramのコメントから)

注意すべきこと:

  • このソリューションは、特定のケースで奇妙な動作をする可能性があります。AまたはBが空で、もう一方が単一の要素を含んでいる場合は、を返しTrueます。なんらかの理由で、比較A==Bによって空の配列allが返され、演算子に対してはその配列が返されますTrue
  • 場合は、別のリスクがあるAB同じ形状を有していないとbroadcastableではありませんん、このアプローチは、エラーが発生します。

結論として、あなたが疑いを抱いているABまたは単に安全を望んでいる場合:特別な機能の1つを使用してください:

np.array_equal(A,B)  # test if same shape, same elements values
np.array_equiv(A,B)  # test if broadcastable shape, same elements values
np.allclose(A,B,...) # test if same shape, elements have close enough values

26
ほとんどの場合、np.array_equalIME が必要です。(A==B).all()ますAとBの長さが異なる場合にクラッシュ。numpy 1.10以降、この場合==は非推奨の警告を出します。
Wilfred Hughes

良い点はありますが、形状に疑問がある場合は、値の前に直接テストするのが通常です。次に、エラーは明らかに、異なる値を持つこととは完全に異なる意味を持つ形状にあります。しかし、それはおそらく各ユースケースに依存します
Juh_

2
別のリスクは、配列にnanが含まれている場合です。その場合、nan!= nan
Vincenzooo

1
それを指摘するのは良いことです。しかし、私はこれがnan!=nan意味するので、これは論理的だと思いますarray(nan)!=array(nan)
Juh_ 2018

この動作は理解できません import numpy as np H = 1/np.sqrt(2)*np.array([[1, 1], [1, -1]]) #hadamard matrix np.array_equal(H.dot(H.T.conj()), np.eye(len(H))) # checking if H is an unitary matrix or not 。Hはユニタリ行列なので、H x H.T.conjは単位行列です。しかし、np.array_equalFalseを返します
Dex

91

(A==B).all()解決策は非常にきれいですが、このタスクのためのいくつかの組み込みの機能があります。すなわちarray_equalallcloseそしてarray_equiv

(ただし、を使用したいくつかの簡単なテストでtimeitは、(A==B).all()メソッドが最も高速であることが示されているようです。まったく新しい配列を割り当てる必要があるため、これは少し変わっています。)


15
正解ですが、比較した配列のいずれかが空の場合、で間違った答えが返されます(A==B).all()。たとえば、(np.array([1])==np.array([])).all()Truenp.array_equal(np.array([1]), np.array([]))False
次のコード

1
このパフォーマンスの違いも発見しました。完全に異なる2つの配列がある場合(a==b).all()でも、np.array_equal(a, b)それは(単一の要素をチェックして終了した可能性がある)よりも高速であるため、これは奇妙です。
Aidan Kane

np.array_equallists of arraysおよびでも動作しdicts of arraysます。これがパフォーマンスの低下の原因である可能性があります。
Bernhard

関数をありがとうallclose、それは私が数値計算に必要なものです。許容範囲内のベクトルの同等性を比較します。:)
loved.by.Jesus 2018

ご注意くださいnp.array_equiv([1,1,1], 1) is True。これは次の理由によります:形状の一貫性とは、それらが同じ形状であること、または1つの入力配列をブロードキャストして他の入力配列と同じ形状を作成できることを意味します。
EliadL

13

次のコードを使用してパフォーマンスを測定しましょう。

import numpy as np
import time

exec_time0 = []
exec_time1 = []
exec_time2 = []

sizeOfArray = 5000
numOfIterations = 200

for i in xrange(numOfIterations):

    A = np.random.randint(0,255,(sizeOfArray,sizeOfArray))
    B = np.random.randint(0,255,(sizeOfArray,sizeOfArray))

    a = time.clock() 
    res = (A==B).all()
    b = time.clock()
    exec_time0.append( b - a )

    a = time.clock() 
    res = np.array_equal(A,B)
    b = time.clock()
    exec_time1.append( b - a )

    a = time.clock() 
    res = np.array_equiv(A,B)
    b = time.clock()
    exec_time2.append( b - a )

print 'Method: (A==B).all(),       ', np.mean(exec_time0)
print 'Method: np.array_equal(A,B),', np.mean(exec_time1)
print 'Method: np.array_equiv(A,B),', np.mean(exec_time2)

出力

Method: (A==B).all(),        0.03031857
Method: np.array_equal(A,B), 0.030025185
Method: np.array_equiv(A,B), 0.030141515

上記の結果によると、numpyメソッドは==演算子とall()メソッドの組み合わせよりも高速であるように見えます。numpyメソッドを比較すると、最も速いのnumpy.array_equalメソッドのようです。


4
実験の精度を上げるには、コンパイルに少なくとも1秒かかる大きな配列サイズを使用する必要があります。
Vikhyat Agarwal

比較の順番を変えても再現しますか?または毎回ランダムにAとBを再初期化しますか?この違いは、AセルとBセルのメモリキャッシングからも説明できます。
またはグローマン

3
これらのタイミングに意味のある違いはありません。
To마SE

13

あなたは、2つの配列が同じを持っているかどうかを確認したい場合shapeelements、あなたが使用する必要がありnp.array_equal、それはマニュアルに推奨される方法ですと。

パフォーマンスに関しては、最適化の余地があまりないため、同等性チェックが他のテストに勝ることを期待しないでくださいcomparing two elements。ちょうどのために、私はまだいくつかのテストを行いました。

import numpy as np
import timeit

A = np.zeros((300, 300, 3))
B = np.zeros((300, 300, 3))
C = np.ones((300, 300, 3))

timeit.timeit(stmt='(A==B).all()', setup='from __main__ import A, B', number=10**5)
timeit.timeit(stmt='np.array_equal(A, B)', setup='from __main__ import A, B, np', number=10**5)
timeit.timeit(stmt='np.array_equiv(A, B)', setup='from __main__ import A, B, np', number=10**5)
> 51.5094
> 52.555
> 52.761

ほぼ同じなので、速度について話す必要はありません。

(A==B).all()かなり多くの次のコードスニペットのように振る舞います。

x = [1,2,3]
y = [1,2,3]
print all([x[i]==y[i] for i in range(len(x))])
> True

5

通常、2つの配列にはいくつかの小さな数値エラーがあります。

numpy.allclose(A,B)代わりにを使用できます(A==B).all()。これはブール値のTrue / Falseを返します


0

ここでを使用しますnp.array_equal。ドキュメントから:

np.array_equal([1, 2], [1, 2])
True
np.array_equal(np.array([1, 2]), np.array([1, 2]))
True
np.array_equal([1, 2], [1, 2, 3])
False
np.array_equal([1, 2], [1, 4])
False
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.