131 votes

convertir la valeur nan à zéro

J'ai un tableau numpy 2D. Certaines des valeurs de ce tableau sont NaN . Je souhaite effectuer certaines opérations à l'aide de ce tableau. Par exemple, considérons le tableau :

[[   0.   43.   67.    0.   38.]
 [ 100.   86.   96.  100.   94.]
 [  76.   79.   83.   89.   56.]
 [  88.   NaN   67.   89.   81.]
 [  94.   79.   67.   89.   69.]
 [  88.   79.   58.   72.   63.]
 [  76.   79.   71.   67.   56.]
 [  71.   71.   NaN   56.  100.]]

J'essaie de prendre chaque ligne, une à la fois, de la trier dans l'ordre inverse pour obtenir les 3 valeurs maximales de la ligne et de calculer leur moyenne. Le code que j'ai essayé est le suivant :

# nparr is a 2D numpy array
for entry in nparr:
    sortedentry = sorted(entry, reverse=True)
    highest_3_values = sortedentry[:3]
    avg_highest_3 = float(sum(highest_3_values)) / 3

Cela ne fonctionne pas pour les lignes contenant NaN . Ma question est la suivante : existe-t-il un moyen rapide de convertir tous les . NaN à zéro dans le tableau numpy 2D afin que je n'aie pas de problèmes avec le tri et les autres choses que j'essaie de faire.

200voto

Paul Points 13042

A est votre tableau 2D :

import numpy as np
A[np.isnan(A)] = 0

La fonction isnan produit un tableau bool indiquant où se trouve le NaN sont. Un tableau booléen peut être utilisé pour indexer un tableau de même forme. Pensez-y comme à un masque.

149voto

Marcin Points 14295

Cela devrait fonctionner :

from numpy import *

a = array([[1, 2, 3], [0, 3, NaN]])
where_are_NaNs = isnan(a)
a[where_are_NaNs] = 0

Dans le cas ci-dessus, where_are_NaNs est :

In [12]: where_are_NaNs
Out[12]: 
array([[False, False, False],
       [False, False,  True]], dtype=bool)

Un complément sur l'efficacité. Les exemples ci-dessous ont été exécutés avec numpy 1.21.2

>>> aa = np.random.random(1_000_000)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit a[np.isnan(a)] = 0
536 µs ± 8.11 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit np.where(np.isnan(a), 0, a)
2.38 ms ± 27.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit np.nan_to_num(a, copy=True)
8.11 ms ± 401 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit np.nan_to_num(a, copy=False)
3.8 ms ± 70.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

En conséquence a[np.isnan(a)] = 0 est plus rapide.

51voto

Drake Points 2306

Pourquoi pas nan_to_num() ?

29voto

Anton Protopopov Points 7767

Vous pouvez utiliser np.where pour savoir où vous avez NaN :

import numpy as np

a = np.array([[   0,   43,   67,    0,   38],
              [ 100,   86,   96,  100,   94],
              [  76,   79,   83,   89,   56],
              [  88,   np.nan,   67,   89,   81],
              [  94,   79,   67,   89,   69],
              [  88,   79,   58,   72,   63],
              [  76,   79,   71,   67,   56],
              [  71,   71,   np.nan,   56,  100]])

b = np.where(np.isnan(a), 0, a)

In [20]: b
Out[20]: 
array([[   0.,   43.,   67.,    0.,   38.],
       [ 100.,   86.,   96.,  100.,   94.],
       [  76.,   79.,   83.,   89.,   56.],
       [  88.,    0.,   67.,   89.,   81.],
       [  94.,   79.,   67.,   89.,   69.],
       [  88.,   79.,   58.,   72.,   63.],
       [  76.,   79.,   71.,   67.,   56.],
       [  71.,   71.,    0.,   56.,  100.]])

17voto

user1587329 Points 91

Un exemple de code pour Réponse de Drake à utiliser nan_to_num :

>>> import numpy as np
>>> A = np.array([[1, 2, 3], [0, 3, np.NaN]])
>>> A = np.nan_to_num(A)
>>> A
array([[ 1.,  2.,  3.],
       [ 0.,  3.,  0.]])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X