2011-02-26 26 views
37

Ho una matrice numpy 2D. Alcuni dei valori di questo array sono NaN. Voglio eseguire determinate operazioni utilizzando questo array. Ad esempio si consideri la matrice:Converti valore nan a zero

[[ 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.]] 

Sto cercando di prendere ogni riga, uno alla volta, specie in ordine inverso per ottenere max 3 valori dalla fila e prendere la loro media. Il codice che è provato:

Questo non funziona per le righe contenenti NaN. La mia domanda è, c'è un modo rapido per convertire tutti i valori NaN a zero nella matrice numpy 2D in modo che non abbia problemi con l'ordinamento e altre cose che sto cercando di fare.

+1

'each: map: return isNaN (value)? 0: value' – kirilloid

+0

@kirilloid: suona bene, che ne dici di un utilizzo di esempio? –

risposta

60

questo dovrebbe funzionare:

from numpy import * 

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

Nel caso di cui sopra where_are_NaNs è:

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

Dove A e il matrice 2D:

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

La funzione isnan produce una matrice booleano che indica dove i valori sono NaN. Un array booleano può essere usato per indicizzare un array della stessa forma. Pensalo come una maschera.

+0

buon modo per impostare – timger

-7

Per i vostri scopi, se tutti gli elementi vengono memorizzati come str e si utilizza solo allineati come si utilizza quindi controlla il primo elemento e sostituiscilo con "0"

>>> l1 = ['88','NaN','67','89','81'] 
>>> n = sorted(l1,reverse=True) 
['NaN', '89', '88', '81', '67'] 
>>> import math 
>>> if math.isnan(float(n[0])): 
...  n[0] = '0' 
... 
>>> n 
['0', '89', '88', '81', '67'] 
+4

Se si utilizza numpy, l'array * non * sarà una rappresentazione in formato stringa di numeri. Sai perfino cos'è il numpy? –

+2

Il tuo commento non è un po 'duro? So che cosa è numpy, ma sapevo che l'array non sarebbe una rappresentazione in numeri di numeri. In particolare, non ho dato una risposta a questo da una prospettiva numpy ma dal punto di vista di Python, se fosse utile. –

+0

Riordinare l'array suona come un modo confuso per risolvere questo problema. – holografix

21

Che dire di nan_to_num()?

+6

nan_to_num() modifica anche gli infiniti, che potrebbero non essere desiderati in alcuni casi. – Agos

+0

È anche> 10 volte più lento rispetto agli altri metodi. – user48956

2

nan non è mai uguale a nan

if z!=z:z=0 

così per una matrice 2D

for entry in nparr: 
    if entry!=entry:entry=0 
+0

Questo non funziona: 'entry' è un array 1D, quindi il test' entry! = Entry' non dà un semplice booleano ma solleva 'ValueError'. – EOL

4

Un esempio di codice per drake's answer da usare 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.]]) 
0

È possibile utilizzare numpy.nan_to_num:

numpy.nan_to_num (x): Sostituire nan con nullo e inf con numeri finiti.

Esempio (vedi doc):

>>> np.set_printoptions(precision=8) 
>>> x = np.array([np.inf, -np.inf, np.nan, -128, 128]) 
>>> np.nan_to_num(x) 
array([ 1.79769313e+308, -1.79769313e+308, 0.00000000e+000, 
     -1.28000000e+002, 1.28000000e+002]) 
0

Si potrebbe utilizzare np.where per trovare dove si hanno 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.]]) 
+1

così com'è, non funziona, è necessario cambiare 'np.where (np.isnan (a), a, 0)' a 'np.where (~ np.isnan (a), a, 0)'. Questa potrebbe essere una differenza nelle versioni utilizzate però. – TehTris

+1

@TehTris hai ragione, grazie. L'ho cambiato in 'b = np.where (np.isnan (a), 0, a)' che è più semplice di '' 'come penso. –

0

È possibile utilizzare la funzione lambda, un esempio per serie 1D:

import numpy as np 
a = [np.nan, 2, 3] 
map(lambda v:0 if np.isnan(v) == True else v, a) 

Questo darà tu il risultato:

[0, 2, 3] 
Problemi correlati