2012-05-14 24 views
131

2つのnumpy配列を等価で比較する最も単純な方法は何ですか(等号はすべてのインデックスiに対してA = B iffとして定義されています)?単に==を使用して2つのnumpy配列を等価の要素で比較する

は私にブール配列を与える:

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

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

は、私は、配列が等しいかどうかを判断するために、この配列の要素をandする必要がありますか、または比較する簡単な方法はありますか?

答えて

197
(A==B).all() 

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

編集(dbauppの答え​​とyoavramさんのコメントから)

ことに留意すべきである:このソリューションは、特定の場合には、奇妙な振る舞いを持つことができます

  • AまたはBのいずれかが空の場合もう一方の要素には1つの要素が含まれている場合は、Trueを返します。なんらかの理由で、比較A==Bは、all演算子がTrueを返す空の配列を返します。
  • ABが同じ形状でなく、ブロードキャスト可能でない場合、この方法ではエラーが発生します。結論として

、私が提案したソリューションは、標準の一つであり、私は思いますが、あなたはAB形状について疑問を持っているか、単に安全になりたい場合:特化した機能のいずれかを使用します。

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 
+7

あなたはほとんど常に 'np.array_equal' IMEをしたい:

(A==B).all()は、次のコードスニペットとしてはかなり動作します。 '(A == B).all()'は、AとBの長さが違うとクラッシュします**。 1.10の時点で、[===この例では推奨されていません](https://github.com/numpy/numpy/commit/6bf0e419dc79ea6815557c57b7e9bb504ba20543)。 –

+0

あなたは良い点を持っていますが、IMEは通常、手前のAとBの形を知っています。私はそれが文脈に依存していると思うし、私が推測する味。 –

64

(A==B).all()ソリューションは非常にきれいですが、このタスクにはいくつかの組み込み関数があります。即ち、array_equal,allclose及びarray_equivである。

timeitといくつかの簡単なテストが(A==B).all()方法は、それが全体の新しい配列を割り当てなければならない与えられた、少し独特である、最速であることを示していると思われる、けれども。)

+10

比較した配列のうちの1つが空の場合、 '(A == B).all()'で間違った答えを得られる点を除いて、あなたは正しいです。例えば、 'np.array_equal(np.array([1])== np.array()])。all()'を実行すると ' )、np.array([])) '' False'を返します – yoavram

+1

私はこのパフォーマンスの違いも発見しました。 '(a == b).all()'は 'np.array_equal(a、b)'よりも高速です(単一の要素をチェックして終了することもできます) 。 –

+0

'np.array_equal'は' lists of arrays'と 'dicts of arrays'でも動作します。これは、パフォーマンスが低下する原因となる可能性があります。 – TheEspinosa

11

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

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の方法は、==オペレータと全て()方法の組み合わせよりによって高速であると思われますnumpyメソッドを比較する最も速いnumpy.array_equalメソッドであるようです。

+0

実験精度を向上させるには、コンパイルするのに少なくとも1秒かかる大規模な配列サイズを使用する必要があります。 –

3

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 

ので、かなり等しい、スピードについて話をする必要はありません。

x = [1,2,3] 
y = [1,2,3] 
print all([True if x[i]==y[i] else False for i in range(len(x))]) 
> True 
関連する問題