Eu tenho uma matriz numpy 2D. Alguns dos valores nesta matriz são NaN
. Quero realizar certas operações usando esta matriz. Por exemplo, considere a 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.]]
Estou tentando pegar cada linha, uma de cada vez, classificá-la em ordem inversa para obter no máximo 3 valores da linha e tirar sua média. O código que tentei é:
# 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
Isso não funciona para linhas contendo NaN
. Minha pergunta é: existe uma maneira rápida de converter todos os NaN
valores para zero no array numpy 2D para que eu não tenha problemas com a classificação e outras coisas que estou tentando fazer.
each: map: return isNaN(value) ? 0 : value
Respostas:
Isso deve funcionar:
from numpy import * a = array([[1, 2, 3], [0, 3, NaN]]) where_are_NaNs = isnan(a) a[where_are_NaNs] = 0
No caso acima, where_are_NaNs é:
In [12]: where_are_NaNs Out[12]: array([[False, False, False], [False, False, True]], dtype=bool)
fonte
Onde
A
está o seu array 2D:import numpy as np A[np.isnan(A)] = 0
A função
isnan
produz um array bool indicando ondeNaN
estão os valores. Um array booleano pode ser usado para indexar um array da mesma forma. Pense nisso como uma máscara.fonte
Que tal nan_to_num () ?
fonte
Você pode usar
np.where
para encontrar onde temNaN
: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.]])
fonte
np.where(np.isnan(a), a, 0)
paranp.where(~np.isnan(a), a, 0)
. Isso pode ser uma diferença nas versões usadas.b = np.where(np.isnan(a), 0, a)
que é mais simples do~
que eu acho.Um exemplo de código para a resposta de Drake usar
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.]])
fonte
Você pode usar numpy.nan_to_num :
Exemplo (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])
fonte
nan nunca é igual a nan
if z!=z:z=0
então, para uma matriz 2D
for entry in nparr: if entry!=entry:entry=0
fonte
entry
é um array 1D, então o testeentry != entry
não fornece um booleano simples, mas aumentaValueError
.Você pode usar a função lambda, um exemplo para matriz 1D:
import numpy as np a = [np.nan, 2, 3] map(lambda v:0 if np.isnan(v) == True else v, a)
Isso lhe dará o resultado:
[0, 2, 3]
fonte
Para seus propósitos, se todos os itens forem armazenados como
str
e você apenas usar classificados como está usando e, em seguida, verifique o primeiro elemento e substitua-o 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']
fonte