2012-05-14 4 views
131

Was ist der einfachste Weg, zwei numpy Arrays für Gleichheit zu vergleichen (wo Gleichheit definiert ist als: A = B iff für alle Indizes i: A[i] == B[i])?Vergleichen von zwei numperigen Arrays für die Gleichheit, elementweise

einfach mit == gibt mir ein boolean-Array:

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

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

Muss ich and haben die Elemente dieses Arrays zu bestimmen, ob die Arrays gleich sind, oder gibt es eine einfachere Art und Weise zu vergleichen?

Antwort

197
(A==B).all() 

testen, ob alle Werte von Array (A == B) True sind.

bearbeiten (von dbaupp Antwort und Kommentar des yoavram)

Es sollte beachtet werden, dass:

  • diese Lösung ein seltsames Verhalten in einem bestimmten Fall haben kann: wenn entweder A oder B ist leer und der andere enthält ein einzelnes Element, dann gibt es True zurück. Aus irgendeinem Grund gibt der Vergleich A==B ein leeres Array zurück, für das der Operator allTrue zurückgibt. Ein anderes Risiko besteht darin, dass A und B nicht die gleiche Form haben und nicht übertragbar sind.

Abschließend die Lösung, die ich vorgeschlagen, ist der Standard ein, glaube ich, aber wenn Sie einen Zweifel über A und B Form haben oder wollen einfach nur um sicher zu sein: eine der spezialisierten Funktionen nutzen:

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

Sie fast immer 'np.array_equal' IME wollen. '(A == B) .all()' wird ** abstürzen, wenn A und B unterschiedliche Längen haben **. Ab 1.10 erhöht [== in diesem Fall eine Verwarnungswarnung] (https://github.com/numpy/numpy/commit/6bf0e419dc79ea6815557c57b7e9bb504ba20543). –

+0

Sie haben einen guten Punkt, aber IME Ich weiß normalerweise, dass die Form von A und B vor der Hand. Ich schätze, es hängt vom Kontext und Geschmack ab, denke ich. –

64

Die (A==B).all() Lösung ist sehr ordentlich, aber es gibt einige eingebaute Funktionen für diese Aufgabe. Nämlich array_equal, allclose und array_equiv.

(Obwohl, einige schnelle Tests mit timeit, dass die (A==B).all() Methode der schnellste ist, um anzuzeigen, scheint, das ist ein wenig seltsam ist, da es eine ganz neue Array zuweisen hat.)

+10

Sie haben Recht, außer dass, wenn eines der verglichenen Arrays leer ist, Sie die falsche Antwort mit '(A == B) .all()' erhalten. Versuchen Sie zum Beispiel: '(np.array ([1]) == np.array ([])). All()', es gibt 'True', während' np.array_equal (np.array ([1]), np.array ([])) 'gibt' False' – yoavram

+1

Ich habe gerade diesen Leistungsunterschied entdeckt. Es ist komisch, denn wenn Sie zwei Arrays haben, die völlig verschieden sind ((a == b) .all() 'ist immer noch schneller als' np.array_equal (a, b) '(das könnte nur ein einzelnes Element überprüft und beendet haben) . –

+0

'np.array_equal' funktioniert auch mit' lists of arrays' und 'dicts of arrays'. Dies könnte ein Grund für eine langsamere Leistung sein. – TheEspinosa

11

ist die Leistung Lassen Sie messen, indem Sie das folgende Stück Code.

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) 

Output

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

die Ergebnisse oben gemäß scheinen die numpy Methoden schneller zu sein, als die Kombination des == Operators und die alle() Verfahren und durch Vergleichen der numpy Methoden der schnellste scheint die numpy.array_equal Methode zu sein.

+0

Sie sollten eine größere Array-Größe verwenden, die mindestens eine Sekunde zum Kompilieren benötigt, um die Testgenauigkeit zu erhöhen. –

3

Wenn Sie überprüfen möchten, ob zwei Arrays die gleichen shape AND elements haben, sollten Sie np.array_equal verwenden, da dies die in der Dokumentation empfohlene Methode ist.

Performance-weise nicht erwarten, dass jede Gleichheitsprüfung eine andere schlagen wird, da es nicht viel Platz zur Optimierung gibt comparing two elements. Nur zum Wohle habe ich noch ein paar Tests gemacht.

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 

So ziemlich gleich, keine Notwendigkeit, über die Geschwindigkeit zu reden.

Die (A==B).all() verhält sich ziemlich viel wie der folgende Code-Schnipsel:

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