Twee NumPy-arrays vergelijken voor gelijkheid, elementsgewijs

Wat is de eenvoudigste manier om twee NumPy-arrays voor gelijkheid te vergelijken (waarbij gelijkheid wordt gedefinieerd als: A = B iff voor alle indices i: A[i] == B[i])?

Gewoon ==gebruiken geeft me een boolean array:

>>> numpy.array([1,1,1]) == numpy.array([1,1,1])
array([ True,  True,  True], dtype=bool)

Moet ik de elementen van deze array andom te bepalen of de arrays gelijk zijn, of is er een eenvoudigere manier om te vergelijken?


Antwoord 1, autoriteit 100%

(A==B).all()

test of alle waarden van array (A==B) waar zijn.

Opmerking: misschien wil je ook A- en B-vorm testen, zoals A.shape == B.shape

Speciale gevallen en alternatieven(van het antwoord van dbaupp en het commentaar van yoavram)

Opgemerkt moet worden dat:

  • deze oplossing kan in een bepaald geval vreemd gedrag vertonen: als Aof Bleeg is en de andere een enkel element bevat, retourneert het True. Om de een of andere reden retourneert de vergelijking A==Been lege array, waarvoor de operator allTrueretourneert.
  • Een ander risico is dat als Aen Bniet dezelfde vorm hebben en niet uitgezonden kunnen worden, deze aanpak een fout oplevert.

Tot slot, als je twijfelt over de vorm Aen Bof gewoon veilig wilt zijn: gebruik een van de gespecialiseerde functies:

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

Antwoord 2, autoriteit 23%

De (A==B).all()oplossing is erg netjes, maar er zijn enkele ingebouwde functies voor deze taak. Namelijk array_equal, allcloseen array_equiv.

(Hoewel wat snelle tests met timeiterop lijken te wijzen dat de (A==B).all()methode de snelste is, wat een beetje vreemd is , aangezien het een geheel nieuwe array moet toewijzen.)


Antwoord 3, autoriteit 3%

Als u wilt controleren of twee arrays dezelfde shapeEN elementshebben, moet u np.array_equalgebruiken, aangezien dit de aanbevolen methode is in de documentatie.

Wat de prestaties betreft, verwacht niet dat de ene gelijkheidscontrole de andere zal verslaan, aangezien er niet veel ruimte is om comparing two elementste optimaliseren. Voor de zekerheid heb ik nog wat tests gedaan.

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

Dus vrijwel gelijk, het is niet nodig om over de snelheid te praten.

De (A==B).all()gedraagt zich ongeveer als het volgende codefragment:

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

Antwoord 4, autoriteit 3%

Laten we de prestaties meten door het volgende stukje code te gebruiken.

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)

Uitvoer

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

Volgens de bovenstaande resultaten lijken de numpy-methoden sneller te zijn dan de combinatie van de ==-operator en de all()-methode en door de numpy-methoden te vergelijken de snelstelijkt de numpy.array_equalmethode te zijn.


Antwoord 5

Gewoonlijk bevatten twee arrays enkele kleine numerieke fouten,

Je kunt numpy.allclose(A,B)gebruiken in plaats van (A==B).all(). Dit geeft een bool True/False


Antwoord 6

Gebruik nu np.array_equal. Uit documentatie:

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

Antwoord 7

Naast de andere antwoorden kun je nu een bewering gebruiken:

numpy.testing.assert_array_equal(x, y)

Je hebt ook een vergelijkbare functie zoals numpy.testing.assert_almost_equal()

https://numpy.org/doc/stable /reference/generated/numpy.testing.asset_array_equal.html

Other episodes