2012-05-14 22 views
131

¿Cuál es la forma más sencilla de comparar dos matrices numpy para la igualdad (donde la igualdad se define como: A = B iff para todos los índices i: A[i] == B[i])?Comparación de dos matrices numpy para la igualdad, elemento-sabio

Simplemente usando == me da una matriz booleana:

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

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

tengo que and los elementos de esta matriz para determinar si los arreglos son iguales, o hay una manera más sencilla de comparar?

Respuesta

197
(A==B).all() 

prueba si todos los valores de la matriz (A == B) son Verdaderos.

Editar (a partir de la respuesta de dbaupp y comentario de yoavram)

Debe tenerse en cuenta que:

  • esta solución puede tener un comportamiento extraño en un caso particular: si bien A o B está vacía y el otro contiene un solo elemento, luego devuelve True. Por alguna razón, la comparación A==B devuelve una matriz vacía, para la cual el operador all devuelve True.
  • Otro riesgo es si A y B no tienen la misma forma y no son de gran escala, entonces este enfoque generará un error.

En conclusión, la solución que se propone es la estándar, creo, pero si usted tiene una duda sobre A y B forma o simplemente quiere estar seguro: utilizar una de las funciones especializadas:

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

Casi siempre quiere 'IME np.array_equal'. '(A == B) .all()' se bloqueará ** si A y B tienen diferentes longitudes **. A partir de numpy 1.10, [== aumenta una advertencia de obsolescencia en este caso] (https://github.com/numpy/numpy/commit/6bf0e419dc79ea6815557c57b7e9bb504ba20543). –

+0

Tienes un buen punto, pero IME generalmente conozco la forma de A y B de antemano. Supongo que depende del contexto, y gusto, supongo. –

64

La solución (A==B).all() es muy ordenada, pero hay algunas funciones integradas para esta tarea. A saber, array_equal, allclose y array_equiv.

(Aunque, algunas pruebas rápidas con timeit parece indicar que el método (A==B).all() es el más rápido, que es un poco peculiar, dado que tiene que asignar un conjunto completamente nuevo.)

+10

tienes razón, excepto que si una de las matrices comparadas está vacía obtendrás la respuesta incorrecta con '(A == B) .all()'. Por ejemplo, intente: '(np.array ([1]) == np.array ([])). All()', da 'True', mientras' np.array_equal (np.array ([1]), np.array ([])) 'da' False' – yoavram

+1

Acabo de descubrir esta diferencia de rendimiento también. Es extraño porque si tienes 2 matrices que son completamente diferentes '(a == b) .all()' es aún más rápido que 'np.array_equal (a, b)' (que podría haber comprobado un solo elemento y haber salido) . –

+0

'np.array_equal' también funciona con' listas de matrices' y 'dicts de matrices'. Esta podría ser una razón para un rendimiento más lento. – TheEspinosa

11

Vamos a medir el rendimiento mediante el uso de la siguiente pieza de código.

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) 

salida

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

De acuerdo con los resultados anteriores, los métodos numpy parece ser más rápido que la combinación de la == operador y el todo() método y por comparando los métodos numpy el más rápido uno parece ser el numpy.array_equal método.

+0

Debe usar un tamaño de matriz mayor que demore al menos un segundo en compilarse para aumentar la precisión del experimento. –

3

Si desea comprobar si dos matrices tienen el mismo shape Y elements, debe usar np.array_equal, ya que es el método recomendado en la documentación.

En cuanto al rendimiento, no espere que cualquier control de igualdad supere a otro, ya que no hay mucho espacio para optimizar comparing two elements. Solo por el bien, aún hice algunas pruebas.

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 

Así que más o menos iguales, no hay necesidad de hablar de la velocidad.

El (A==B).all() se comporta más o menos como el siguiente fragmento de código:

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 
Cuestiones relacionadas