Eşitlik için iki NumPy dizisini element bakımından karşılaştırma


252

Eşitlik için iki NumPy dizisini karşılaştırmanın en basit yolu nedir (eşitlik şu şekilde tanımlanır: A = B tüm endeksler için iff i:) A[i] == B[i]?

Sadece kullanmak ==bana bir boolean dizisi verir:

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

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

andDizilerin eşit olup olmadığını belirlemek için bu dizinin öğelerine ihtiyacım var mı yoksa karşılaştırmanın daha basit bir yolu var mı?

Yanıtlar:


380
(A==B).all()

dizinin tüm değerlerinin (A == B) Doğru olup olmadığını test edin.

Not: belki de A ve B şeklini test etmek istersiniz, örneğin A.shape == B.shape

Özel durumlar ve alternatifler (dbaupp cevabından ve yoavram'ın yorumundan)

Bu not alınmalı:

  • bu çözüm belirli bir durumda garip bir davranış sergileyebilir: ya Aya Bboşsa, diğeri tek bir öğe içeriyorsa, geri döner True. Bazı nedenlerle karşılaştırma A==B, alloperatörün döndürdüğü boş bir dizi döndürür True.
  • Eğer başka risktir Ave Baynı şekle sahip değildir ve broadcastable değillerdir, o zaman bu yaklaşımın bir hata yükseltecektir.

Sonuç olarak, hakkında şüpheniz varsa Ave Bşekillendiriyorsanız veya sadece güvenli olmak istiyorsanız: özel işlevlerden birini kullanın:

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
Neredeyse her zaman np.array_equalIME istiyorsun . (A==B).all()olacak A ve B farklı uzunlukları varsa çökmesine . Numpy 1.10 itibariyle, == bu durumda kullanımdan kaldırma uyarısı verir .
Wilfred Hughes

İyi bir noktanız var, ancak şekilden şüphe duyduğumda, değerden önce genellikle doğrudan test etmeyi tercih ederim. O zaman hata, farklı değerlere sahip olmaktan tamamen farklı bir anlama sahip şekiller üzerinde açıkça görülür. Ancak bu muhtemelen her kullanım durumuna bağlıdır
Juh_

2
diğer bir risk dizilerin nan içeriyor olması. Bu durumda False alacaksınız çünkü nan! = Nan
Vincenzooo

1
Belirtmek güzel. Ancak, bunun mantıklı olduğunu düşünüyorum çünkü bunu nan!=nanima ediyor array(nan)!=array(nan).
Juh_

Bu davranışı anlamıyorum: 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 birimsel bir matristir, bu nedenle Hx H.T.conjbir kimlik matrisidir. Ancak np.array_equalFalse döndürür
Dex

91

(A==B).all()Çözüm çok düzgün olduğunu, ancak bu görev için bazı yerleşik işlevler vardır. Yani array_equal, allcloseve array_equiv.

(Bununla birlikte, bazı hızlı testler, yepyeni bir dizi ayırması timeitgerektiğinde, (A==B).all()yöntemin en hızlı olduğunu gösterir , bu biraz tuhaftır.)


15
haklısınız, ancak karşılaştırılan dizilerden biri boşsa yanlış yanıtı alırsınız (A==B).all(). Örneğin, şunu deneyin: (np.array([1])==np.array([])).all()verir True, np.array_equal(np.array([1]), np.array([]))verirFalse
yoavram

1
Ben de bu performans farkını keşfettim. Gariptir, çünkü tamamen farklı 2 diziniz varsa (a==b).all()hala daha hızlıdır np.array_equal(a, b)(sadece tek bir elemanı kontrol edip çıkmış olabilir).
Aidan Kane

np.array_equallists of arraysve ile de çalışır dicts of arrays. Bu, daha yavaş bir performans için bir neden olabilir.
Bernhard

İşlev için çok teşekkürler allclose, sayısal hesaplamalar için ihtiyacım olan şey bu . Bir tolerans dahilinde vektörlerin eşitliğini karşılaştırır . :)
loved.by.Jesus

Unutmayın np.array_equiv([1,1,1], 1) is True. Bunun nedeni: Şekil tutarlı olmaları, ya aynı şekle sahip oldukları veya bir giriş dizisinin diğeriyle aynı şekli oluşturmak için yayınlanabileceği anlamına gelir.
EliadL

13

Aşağıdaki kod parçasını kullanarak performansı ölçelim.

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)

Çıktı

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

Yukarıdaki sonuçlara göre, numpy yöntemleri == operatörü ve all () yönteminin kombinasyonundan daha hızlı görünmektedir ve numpy yöntemleri karşılaştırılarak en hızlı olan numpy.array_equal yöntemi gibi görünmektedir .


4
Deneme doğruluğunu artırmak için derlenmesi en az saniye süren daha büyük bir dizi boyutu kullanmalısınız.
Vikhyat Agarwal

Karşılaştırma sırası değiştiğinde bu da yeniden ortaya çıkıyor mu? ya da A ve B'yi her seferinde rastgele yeniden başlatmak Bu fark, A ve B hücrelerinin hafıza önbelleklemesinden de açıklanabilir.
Veya Groman

3
Bu zamanlamalar arasında anlamlı bir fark yoktur.
SE

13

İki dizinin aynı olup olmadığını kontrol etmek istiyorsanız shapeVE belgelerinde önerilen yöntemle elementskullanmalısınız np.array_equal.

Performans açısından, herhangi bir eşitlik kontrolünün diğerini geçmesini beklemeyin, çünkü optimize edilecek çok yer yoktur comparing two elements. Sadece uğruna, hala bazı testler yaptım.

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

Çok eşit, hız hakkında konuşmaya gerek yok.

(A==B).all()Hemen hemen aşağıdaki kod pasajı olarak davranacağını:

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

5

Genellikle iki dizide bazı küçük sayısal hatalar olur,

Bunun numpy.allclose(A,B)yerine kullanabilirsiniz (A==B).all(). Bu bir bool True / False döndürür


0

Şimdi kullanın np.array_equal. Belgelerden:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.