nan 값을 0으로 변환


95

2D numpy 배열이 있습니다. 이 배열의 일부 값은 NaN. 이 배열을 사용하여 특정 작업을 수행하고 싶습니다. 예를 들어 배열을 고려하십시오.

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

각 행을 한 번에 하나씩 가져 와서 역순으로 정렬하여 행에서 최대 3 개의 값을 가져와 평균을 가져 오려고합니다. 내가 시도한 코드는 다음과 같습니다.

# 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

이 포함 된 행에는 작동하지 않습니다 NaN. 제 질문은 NaN2D numpy 배열에서 모든 값을 0 으로 변환하는 빠른 방법이 있으므로 정렬 및 수행하려는 다른 작업에 문제가 없습니다.


1
each: map: return isNaN(value) ? 0 : value
kirilloid

@kirilloid : 좋은 것 같네요. 예제 사용은 어떻습니까?
serv-inc

답변:


123

이것은 작동합니다.

from numpy import *

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

위의 경우 where_are_NaNs는 다음과 같습니다.

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

138

A2D 어레이는 어디에 있습니까?

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

이 함수 isnanNaN값이 있는 위치를 나타내는 bool 배열을 생성합니다 . 부울 배열은 동일한 모양의 배열을 인덱싱하는 데 사용할 수 있습니다. 마스크처럼 생각하십시오.


40

방법에 대한 nan_to_num () ?


11
nan_to_num () 또한 무한도를 변경합니다. 이는 경우에 따라 원하지 않을 수 있습니다.
Agos

11
또한 다른 방법보다 10 배 이상 느립니다.
user48956

7
나는 tat "> 10x slow"진술에 대해 확신하지 못해서 확인했다. 실제로 훨씬 느립니다. 지적 해 주셔서 감사합니다.
Gabriel

16

당신이 np.where있는 곳을 찾는 데 사용할 수 있습니다 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
그대로, 그것은 작품을 나던, 당신은 변화를 필요 np.where(np.isnan(a), a, 0)np.where(~np.isnan(a), a, 0). 이것은 사용되는 버전의 차이 일 수 있습니다.
TehTris

1
@TehTris 당신이 맞아요, 감사합니다. 내가 생각 b = np.where(np.isnan(a), 0, a)하는 것보다 더 간단하게 변경했습니다 ~.
Anton Protopopov

10

사용에 대한 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.]])

3

numpy.nan_to_num 사용할 수 있습니다 .

numpy.nan_to_num (x) : nan0으로 , inf유한 숫자로 바꿉니다 .

예 (문서 참조) :

>>> 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])

1

nan은 결코 nan과 같지 않습니다.

if z!=z:z=0

그래서 2D 배열의 경우

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

이것은 작동하지 않습니다 : entry1D 배열이므로 테스트 entry != entry는 간단한 부울을 제공하지 않고 ValueError.
Eric O Lebigot 2017-08-05

-1

1D 배열의 예인 람다 함수를 사용할 수 있습니다.

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

결과를 얻을 수 있습니다.

[0, 2, 3]

-8

귀하의 목적을 위해 모든 항목이 다음 str과 같이 저장되어 있고 사용하는대로 정렬 된 상태로 사용하고 첫 번째 요소를 확인하고 '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']

6
귀하의 의견이 조금 가혹하지 않습니까? 나는 numpy가 무엇인지 알고 있지만 배열이 숫자의 문자열 표현이 아니라는 것을 알고 있습니다. 나는 특별히 numpy 관점에서 이것을 다루지 않았지만 그것이 유용하다면 파이썬의 관점에서 다루었습니다.
Senthil Kumaran

2
배열을 재정렬하는 것은이 문제를 해결하는 데 혼란스러운 방법처럼 들립니다.
holografix 2014-06-21

배열 순서를 유지해야합니다. 배열에 여러 개의 'NaN'이 있으면 작동하지 않습니다.
3nrique0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.