Comparaison de deux tableaux numpy pour l'égalité, élément par élément
Quel est le moyen le plus simple de comparer deux tableaux numpy pour l'égalité (où l'égalité est définie comme: A = B iff pour tous les indices i: A[i] == B[i]
)?
Utiliser simplement ==
me donne un tableau booléen:
>>> numpy.array([1,1,1]) == numpy.array([1,1,1])
array([ True, True, True], dtype=bool)
Dois-je and
les éléments de ce tableau pour déterminer si les matrices sont égales, ou est-il un moyen plus simple pour comparer?
4 réponses
(A==B).all()
Testez si toutes les valeurs du tableau (A= = B) sont vraies.
Edit (de la réponse de dbaupp et du commentaire de yoavram)
, Il convient de noter que:
- cette solution peut avoir un comportement étrange, dans un cas particulier: si
A
ouB
est vide et l'autre contient un seul élément, puis retournerTrue
. Pour une raison quelconque, la comparaisonA==B
renvoie un tableau vide, pour qui laall
opérateur retourneTrue
. - un autre risque est si
A
etB
n'ont pas la même forme et ne sont pas diffusables, alors cette approche provoquera une erreur.
En conclusion, la solution que j'ai proposée est la norme, je pense, mais si vous avez un doute à propos de A
et B
forme ou simplement pour être sûr: utilisez l'une des fonctions spécialisées:
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
La solution (A==B).all()
est très soignée, mais il y a quelques fonctions intégrées pour cette tâche. À savoir array_equal
, allclose
et array_equiv
.
(Bien que certains tests rapides avec timeit
semblent indiquer que la méthode (A==B).all()
est la plus rapide, ce qui est un peu particulier, étant donné qu'elle doit allouer un tout nouveau tableau.)
Mesurons la performance en utilisant le morceau de code suivant.
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)
Sortie
Method: (A==B).all(), 0.03031857
Method: np.array_equal(A,B), 0.030025185
Method: np.array_equiv(A,B), 0.030141515
Selon les résultats ci-dessus, le numpy méthodes semblent être plus rapide que la combinaison de la == de l'opérateur et de la tous() méthode et en comparant les numpy méthodes le plus rapide semble être le numpy.méthode array_equal .
Si vous voulez vérifier si deux tableaux ont les mêmes shape
et elements
vous devez utiliser np.array_equal
car c'est la méthode recommandée dans la documentation.
En termes de performances, ne vous attendez pas à ce qu'un contrôle d'égalité en batte un autre, car il n'y a pas beaucoup de place pour optimiser
comparing two elements
. Juste pour le plaisir, j'ai encore fait quelques tests.
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
Donc à peu près égale, pas besoin de parler de la vitesse.
Le (A==B).all()
se comporte à peu près comme l'extrait de code suivant:
x = [1,2,3]
y = [1,2,3]
print all([x[i]==y[i] for i in range(len(x))])
> True