2011-02-26 27 views
37

Tengo una matriz numpy 2D. Algunos de los valores en esta matriz son NaN. Quiero realizar ciertas operaciones usando esta matriz. Por ejemplo, consideremos la matriz:convertir valor de nan a cero

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

Estoy tratando de tomar cada fila, uno a la vez, más o menos en orden inverso para obtener un máximo de 3 valores de la fila y tomar su promedio. El código que he probado es:

Esto no funciona para las filas que contienen NaN. Mi pregunta es, ¿hay una forma rápida de convertir todos los valores NaN a cero en la matriz numpy 2D para que no tenga problemas con la ordenación y otras cosas que estoy tratando de hacer.

+1

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

+0

@kirilloid: suena bien, ¿qué tal el uso de ejemplos? –

Respuesta

60

esto debería funcionar:

from numpy import * 

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

En el caso anterior where_are_NaNs es:

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

Dónde A es su matriz 2D:

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

La función isnan produce una matriz bool indicando si las NaN valores son. Una matriz booleana puede usarse para indexar una matriz de la misma forma. Piénsalo como una máscara.

+0

buena manera de establecer – timger

-7

para sus propósitos, si todos los artículos se almacenan como str y usted sólo tiene que utilizar ordenadas como lo está haciendo y luego buscar el primer elemento y reemplazarlo por '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

Si está usando numpy, su matriz * no * será una cadena de representación de números. ¿Sabes qué es numpy? –

+2

¿No es un comentario áspero? Sé lo que es numpy, pero sabía que la matriz no sería una representación en cadena de números. Específicamente no le di un vistazo a esto desde la perspectiva numpy pero desde la perspectiva de Python, si eso fue útil. –

+0

Reordenar la matriz suena como una forma confusa de resolver esto. – holografix

21

¿Qué tal nan_to_num()?

+6

nan_to_num() también cambia infinidades; esto podría no ser deseado en algunos casos. – Agos

+0

También es> 10 veces más lento que los otros métodos. – user48956

2

nan nunca es igual a nan

if z!=z:z=0 

así que para una matriz 2D

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

Esto no funciona: 'entry' es una matriz 1D, por lo que la prueba' entry! = Entry' no da un booleano simple sino que levanta 'ValueError'. – EOL

4

Un ejemplo de código para drake's answer utilizar 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

Usted puede utilizar numpy.nan_to_num:

numpy.nan_to_num (x): Reemplazar nan con cero y inf con números finitos.

Ejemplo (ver 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

Usted podría utilizar np.where para encontrar donde se tiene 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

como está, no funciona, debe cambiar 'np.where (np.isnan (a), a, 0)' a 'np.where (~ np.isnan (a), a, 0)'. Sin embargo, esto podría ser una diferencia en las versiones utilizadas. – TehTris

+1

@TehTris tienes razón, gracias. Lo cambié a 'b = np.where (np.isnan (a), 0, a)' que es más directo que con '~' como creo. –

0

Puede utilizar la función lambda, un ejemplo de matriz de 1D:

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

Esto le dará usted el resultado:

[0, 2, 3] 
Cuestiones relacionadas