comparando matrices numpy que contienen NaN

Para mi prueba de unidad, quiero comprobar si dos matrices son idénticas. Ejemplo reducido:

a = np.array([1, 2, np.NaN]) b = np.array([1, 2, np.NaN]) if np.all(a==b): print 'arrays are equal' 

Esto no funciona porque nan! = Nan. ¿Cuál es la mejor manera de proceder?

Gracias por adelantado.

Alternativamente, puede usar numpy.testing.assert_equal o numpy.testing.assert_array_equal con un try/except :

 In : import numpy as np In : def nan_equal(a,b): ...: try: ...: np.testing.assert_equal(a,b) ...: except AssertionError: ...: return False ...: return True In : a=np.array([1, 2, np.NaN]) In : b=np.array([1, 2, np.NaN]) In : nan_equal(a,b) Out: True In : a=np.array([1, 2, np.NaN]) In : b=np.array([3, 2, np.NaN]) In : nan_equal(a,b) Out: False 

Editar

Ya que está usando esto para la prueba de unidad, afirmación assert (en lugar de envolverla para obtener True/False ) podría ser más natural.

No estoy seguro de que esta sea la mejor manera de proceder, pero es una forma:

 >>> ((a == b) | (numpy.isnan(a) & numpy.isnan(b))).all() True 

La forma más fácil es usar el método numpy.allclose() , que permite especificar el comportamiento cuando se tienen valores nan. Entonces tu ejemplo se verá como el siguiente:

 a = np.array([1, 2, np.nan]) b = np.array([1, 2, np.nan]) if np.allclose(a, b, equal_nan=True): print 'arrays are equal' 

Entonces las arrays are equal se imprimirán.

Puedes encontrar aquí la documentación relacionada.

Puede usar matrices enmascaradas numpy, enmascarar los valores de NaN y luego usar numpy.ma.all o numpy.ma.allclose :

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.all.html

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.allclose.html

Por ejemplo:

 a=np.array([1, 2, np.NaN]) b=np.array([1, 2, np.NaN]) np.ma.all(np.ma.masked_invalid(a) == np.ma.masked_invalid(b)) #True 

Cuando utilicé la respuesta anterior:

  ((a == b) | (numpy.isnan(a) & numpy.isnan(b))).all() 

Me dio algunos errores al evaluar la lista de cadenas.

Esto es más tipo genérico:

 def EQUAL(a,b): return ((a == b) | ((a != a) & (b != b))) 

Si hace esto para cosas como pruebas de unidad, por lo que no le importa mucho el rendimiento y el comportamiento “correcto” con todos los tipos, puede usar esto para tener algo que funcione con todos los tipos de arrays, no solo numéricos :

 a = np.array(['a', 'b', None]) b = np.array(['a', 'b', None]) assert list(a) == list(b) 

ndarray s a list s a veces puede ser útil para obtener el comportamiento que desea en algunas pruebas. (¡Pero no use esto en el código de producción, o con arreglos más grandes!)