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?

149
demandé sur smci 2012-05-14 13:30:18

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 ou B est vide et l'autre contient un seul élément, puis retourner True. Pour une raison quelconque, la comparaison A==B renvoie un tableau vide, pour qui la all opérateur retourne True.
  • un autre risque est si A et B 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
224
répondu Juh_ 2014-10-06 07:56:59

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.)

70
répondu huon 2012-05-14 11:00:58

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 .

12
répondu funk 2016-02-23 13:42:04

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
4
répondu user1767754 2018-04-30 00:44:52