Tengo una matriz de números 2D. Algunos de los valores de esta matriz son NaN
. Quiero realizar ciertas operaciones usando esta matriz. Por ejemplo, considere la matriz:
[[ 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, una a la vez, ordenarlas en orden inverso para obtener un máximo de 3 valores de la fila y tomar su promedio. El código que probé es:
# 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
Esto no funciona para filas que contienen NaN
. Mi pregunta es, ¿existe una manera rápida de convertir todos los NaN
valores a cero en la matriz numérica 2D para que no tenga problemas con la clasificación y otras cosas que estoy tratando de hacer?
each: map: return isNaN(value) ? 0 : value
Respuestas:
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)
fuente
¿Dónde
A
está tu matriz 2D?import numpy as np A[np.isnan(A)] = 0
La función
isnan
produce una matriz bool que indica dónde están losNaN
valores. Una matriz booleana se puede usar para indexar una matriz de la misma forma. Piense en ello como una máscara.fuente
¿Qué tal nan_to_num () ?
fuente
Puede utilizar
np.where
para encontrar dónde tieneNaN
: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.]])
fuente
np.where(np.isnan(a), a, 0)
anp.where(~np.isnan(a), a, 0)
. Sin embargo, esto podría ser una diferencia en las versiones utilizadas.b = np.where(np.isnan(a), 0, a)
que es más sencillo que con~
lo que creo.Un ejemplo de código para usar la respuesta de Drake
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.]])
fuente
Puede usar numpy.nan_to_num :
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])
fuente
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
fuente
entry
es una matriz 1D, por lo que la pruebaentry != entry
no da un booleano simple sino que aumentaValueError
.Puede usar la función lambda, un ejemplo de matriz 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á el resultado:
[0, 2, 3]
fuente
Para sus propósitos, si todos los elementos se almacenan como
str
y solo usa sorted como lo está usando y luego verifique el primer elemento y reemplácelo 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']
fuente