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.