web-dev-qa-db-fra.com

comparer des tableaux numpy contenant NaN

Pour mon unittest, je veux vérifier si deux tableaux sont identiques. Exemple réduit: 

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

Cela ne fonctionne pas car nan! = Nan . Quelle est la meilleure façon de procéder?

Merci d'avance.

41
saroele

Vous pouvez aussi utiliser numpy.testing.assert_equal ou numpy.testing.assert_array_equal avec 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

Modifier

Puisque vous utilisez ceci pour unittesting, assert (au lieu de l’emballer pour obtenir True/False) pourrait être plus naturel.

29
Avaris

Je ne suis pas sûr que ce soit la meilleure façon de procéder, mais c'est une

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

La méthode la plus simple consiste à utiliser la méthode numpy.allclose(), qui permet de spécifier le comportement lorsqu’on a des valeurs nan. Ensuite, votre exemple ressemblera à ceci:

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'

Alors arrays are equal sera imprimé.

Vous pouvez trouver ici la documentation associée

13

Vous pouvez utiliser des tableaux masqués numpy, masquer les valeurs NaN puis utiliser numpy.ma.all ou 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

Par exemple:

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
9
JoshAdel

Quand j'ai utilisé la réponse ci-dessus:

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

Cela m'a donné des erreurs lors de l'évaluation de la liste des chaînes.

C'est plus de type générique:

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

Si vous faites cela pour des choses comme unit tests, pour ne pas vous soucier de la performance et du comportement «correct» avec tous les types, vous pouvez utiliser ceci pour avoir quelque chose qui fonctionne avec tous les types de tableaux, juste numérique:

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

Transférer ndarrays en lists peut parfois être utile pour obtenir le comportement souhaité dans certains tests. (Mais ne l'utilisez pas dans le code de production ou avec des tableaux plus grands!)

0
NeuronQ