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 NaNvalores 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 : valueRespuestas:
Esto debería funcionar:
from numpy import * a = array([[1, 2, 3], [0, 3, NaN]]) where_are_NaNs = isnan(a) a[where_are_NaNs] = 0En 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
Aestá tu matriz 2D?import numpy as np A[np.isnan(A)] = 0La función
isnanproduce una matriz bool que indica dónde están losNaNvalores. 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.wherepara 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=0así que para una matriz 2D
for entry in nparr: if entry!=entry:entry=0fuente
entryes una matriz 1D, por lo que la pruebaentry != entryno 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
stry 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