배열에서 nan 값 제거


223

배열에서 nan 값을 제거하는 방법을 알고 싶습니다. 내 배열은 다음과 같습니다.

x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration

에서 nan값을 x어떻게 제거 합니까?


분명히, "NaN 제거" 는 널이 아닌 값의 서브 세트 만 필터링 함을 의미 합니다 . "NaN을 어떤 값 (0, 상수, 평균, 중간 값 등)으로
채우지 마십시오

답변:


362

배열에 numpy를 사용하는 경우 다음을 사용할 수도 있습니다

x = x[numpy.logical_not(numpy.isnan(x))]

동등하게

x = x[~numpy.isnan(x)]

[추가 된 속기 덕분에 chbrown에게 감사합니다]

설명

내부 함수 는 숫자가 아닌 모든 numpy.isnan값을 갖는 부울 / 논리 배열을 반환합니다 . 우리가 반대 할 때, 우리는 논리되지 연산자를 사용 과 배열을 가져 오는 그 모든 곳들 입니다 유효한 번호.Truex~Truex

마지막으로이 논리 형 배열을 사용 x하여 NaN 이외의 값만 검색하기 위해 원래 배열로 색인을 생성 합니다.


31
또는x = x[numpy.isfinite(x)]
lazy1

14
또는 x = x[~numpy.isnan(x)], 이것은 mutzmatron의 원래 답변과 동일하지만 짧습니다. 인피니티를 유지하고 싶다면 numpy.isfinite(numpy.inf) == False물론 ~numpy.isnan(numpy.inf) == True.
chbrown

8
사람들은 사용 ndarray으로이 문제를 해결하고 크기를 유지하기 위해 찾고 들어 NumPy와 어디 :np.where(np.isfinite(x), x, 0)
BoltzmannBrain

1
형식 오류 : 스칼라 배열은 스칼라 인덱스로 변환 할 수있는 유일한 정수
towry

1
@ towry : 이것은 입력 x이 numpy 배열이 아니기 때문에 발생합니다 . 논리적 인덱싱을 사용하려면 배열이어야합니다. 예 :x = np.array(x)
jmetz

50
filter(lambda v: v==v, x)

v! = v 이후 NaN에 대해서만리스트와 numpy 배열에 모두 작동합니다.


5
해킹이지만 문자열 및 nan과 같은 혼합 유형의 객체 배열에서 nan을 필터링하는 경우 특히 유용합니다.
Austin Richardson

매우 깨끗한 솔루션.
Moondra

2
이것은 영리 해 보일 수 있지만, 논리를 모호하게하면 이론적으로 다른 객체 (예 : 커스텀 클래스)도이 속성을 가질 수 있습니다
Chris_Rands

또한 x유형의 솔루션과 달리 한 번만 지정하면 되므로 유용 합니다 x[~numpy.isnan(x)]. 이것은 x긴 표현식으로 정의 될 때 편리 하며이 긴 표현식의 결과를 저장하기 위해 임시 변수를 작성하여 코드를 어지럽히고 싶지 않습니다.
기독교 오라일리

34

이 시도:

import math
print [value for value in x if not math.isnan(value)]

자세한 내용은 List Comprehensions를 참조하십시오 .


5
numpy를 사용하는 경우 내 대답과 @ lazy1에 의한 답변은 목록 이해보다 거의 10 배 빠릅니다 .lazy1의 솔루션은 약간 빠릅니다 (기술적으로는 무한대 값을 반환하지는 않지만).
jmetz

대괄호를 잊지 마십시오 :)print ([value for value in x if not math.isnan(value)])
hypers

상단 답변과 같은 numpy를 사용하는 경우 np패키지 와 함께이 목록 이해 답변을 사용할 수 있습니다 . 따라서 nans없이 목록을 반환합니다.[value for value in x if not np.isnan(value)]
yeliabsalohcin

23

나에게 @jmetz의 대답은 효과가 없었지만 팬더를 사용하면 isnull ()을 사용했습니다.

x = x[~pd.isnull(x)]

6

위를 수행 :

x = x[~numpy.isnan(x)]

또는

x = x[numpy.logical_not(numpy.isnan(x))]

동일한 변수 (x)로 재설정해도 실제 nan 값이 제거되지 않고 다른 변수를 사용해야한다는 것을 알았습니다. 다른 변수로 설정하면 nan이 제거되었습니다. 예 :

y = x[~numpy.isnan(x)]

이건 이상해; docs 에 따르면 , 부울 배열 인덱싱 (이것은)은 고급 인덱싱 을 받고 있으며 "항상 데이터 사본을 반환합니다"라는 새로운 인덱싱 을 받고 있으므로 x새 값 으로 덮어 써야합니다 (즉, NaN이없는 경우 ...) . 왜 이런 일이 발생할 수 있는지 더 많은 정보를 제공 할 수 있습니까?
jmetz

5

다른 사람들이 보듯이

x[~numpy.isnan(x)]

공장. 그러나 numpy dtype이 기본 데이터 유형이 아닌 경우 (예 : 객체 인 경우) 오류가 발생합니다. 이 경우 팬더를 사용할 수 있습니다.

x[~pandas.isna(x)] or x[~pandas.isnull(x)]

4

허용 대답은 2 차원 배열의 모양을 변경합니다. Pandas dropna () 기능을 사용하여 여기에 해결책을 제시 합니다. 1D 및 2D 배열에서 작동합니다. 2D 경우 날씨를 선택하여을 포함 하는 행 또는 열드롭 할 수 있습니다 np.nan.

import pandas as pd
import numpy as np

def dropna(arr, *args, **kwarg):
    assert isinstance(arr, np.ndarray)
    dropped=pd.DataFrame(arr).dropna(*args, **kwarg).values
    if arr.ndim==1:
        dropped=dropped.flatten()
    return dropped

x = np.array([1400, 1500, 1600, np.nan, np.nan, np.nan ,1700])
y = np.array([[1400, 1500, 1600], [np.nan, 0, np.nan] ,[1700,1800,np.nan]] )


print('='*20+' 1D Case: ' +'='*20+'\nInput:\n',x,sep='')
print('\ndropna:\n',dropna(x),sep='')

print('\n\n'+'='*20+' 2D Case: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna (rows):\n',dropna(y),sep='')
print('\ndropna (columns):\n',dropna(y,axis=1),sep='')

print('\n\n'+'='*20+' x[np.logical_not(np.isnan(x))] for 2D: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna:\n',x[np.logical_not(np.isnan(x))],sep='')

결과:

==================== 1D Case: ====================
Input:
[1400. 1500. 1600.   nan   nan   nan 1700.]

dropna:
[1400. 1500. 1600. 1700.]


==================== 2D Case: ====================
Input:
[[1400. 1500. 1600.]
 [  nan    0.   nan]
 [1700. 1800.   nan]]

dropna (rows):
[[1400. 1500. 1600.]]

dropna (columns):
[[1500.]
 [   0.]
 [1800.]]


==================== x[np.logical_not(np.isnan(x))] for 2D: ====================
Input:
[[1400. 1500. 1600.]
 [  nan    0.   nan]
 [1700. 1800.   nan]]

dropna:
[1400. 1500. 1600. 1700.]

3

당신이 사용하는 경우 numpy

# first get the indices where the values are finite
ii = np.isfinite(x)

# second get the values
x = x[ii]


0

이것은 NaN 및 infs에 대해 ndarray "X" 를 필터링하는 방법입니다 .

나는 어떤없이 행의지도를 작성 NaN하고 inf다음과 같이 :

idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))

idx는 튜플입니다. 두 번째 열 ( idx[1])에는 NaN 이나 inf 가없는 배열의 인덱스가 포함됩니다. 있으며 행에서 를 찾을 수 .

그때:

filtered_X = X[idx[1]]

filtered_Xnor 없이 X 포함합니다 .NaNinf


0

@jmetz의 답변 은 아마도 대부분의 사람들이 필요로하는 것입니다. 그러나 1 차원 배열을 생성합니다. 예를 들어 행렬에서 전체 행이나 열을 제거 할 수 없게합니다.

그렇게하려면 논리 배열을 1 차원으로 줄이고 대상 배열을 색인화해야합니다. 예를 들어, 다음은 하나 이상의 NaN 값을 가진 행을 제거합니다.

x = x[~numpy.isnan(x).any(axis=1)]

자세한 내용은 여기를 참조 하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.