source

NumPy 어레이에서 NaN 값을 삭제하려면 어떻게 해야 합니까?

nicesource 2022. 11. 24. 20:44
반응형

NumPy 어레이에서 NaN 값을 삭제하려면 어떻게 해야 합니까?

NumPy 어레이에서 NaN 값을 삭제하려면 어떻게 해야 합니까?

[1, 2, NaN, 4, NaN, 8]   ⟶   [1, 2, 4, 8]

NumPy 배열에서 NaN 값을 제거하려면 다음과 같이 하십시오.x:

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

내부 기능numpy.isnan값을 가진 부울/논리 배열을 반환합니다.True도처에xnot-a-number 입니다.반대이기 때문에 논리연산자를 사용합니다.~정렬하다True어디에나 있다x 유효한 숫자입니다.

마지막으로 이 논리 어레이를 사용하여 원래 어레이에 인덱싱합니다.xNaN 이외의 값만 취득합니다.

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

v!=v가 NaN에 대해서만 작동하므로 목록과 numpy 배열 모두에 대해 작동합니다.

이것을 시험해 보세요.

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

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

@jmetz의 답변은 효과가 없었지만 판다 isull()을 사용하는 것은 효과가 있었습니다.

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

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

그러기 위해서는 논리 어레이를 1차원으로 줄이고 타깃 어레이를 인덱스해야 합니다.예를 들어, 다음 명령어는 적어도1개의 NaN 값을 가진 행을 삭제합니다.

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

자세한 것은 이쪽을 참조해 주세요.

다른 사람이 나타내듯이

x[~numpy.isnan(x)]

numpy dtype이 네이티브 데이터 타입이 아닌 경우(예를 들어 객체인 경우) 오류가 발생합니다.그럴 때는 판다를 이용해도 됩니다.

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

사용하시는 경우numpy

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

# second get the values
x = x[ii]

위의 작업을 수행합니다.

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

또는

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

동일한 변수(x)로 리셋해도 실제 nan 값이 제거되지 않아 다른 변수를 사용해야 한다는 것을 알게 되었습니다.다른 변수로 설정하면 다음과 같이 난이 제거되었습니다.

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

승인된 답변은 2D 배열의 모양을 변경합니다.Panda 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.]

심플한 1D 어레이의 경우 도움이 되는 경우:

x = np.array([np.nan, 1, 2, 3, 4])

x[~np.isnan(x)]
>>> array([1., 2., 3., 4.])

그러나 행렬로 확장하고 모양을 유지하려는 경우:

x = np.array([
    [np.nan, np.nan],
    [np.nan, 0],
    [1, 2],
    [3, 4]
])

x[~np.isnan(x).any(axis=1)]
>>> array([[1., 2.],
           [3., 4.]])

나는 판다를 다루면서 이 문제를 만났다..shift()이 기능을 사용하는 것은 피하고 싶었습니다..apply(..., axis=1)그 비효율성 때문에 어떤 대가를 치르더라도 말이죠.

간단히 채우다

 x = numpy.array([
 [0.99929941, 0.84724713, -0.1500044],
 [-0.79709026, numpy.NaN, -0.4406645],
 [-0.3599013, -0.63565744, -0.70251352]])

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

print(x)

# [[ 0.99929941  0.84724713 -0.1500044 ]
#  [-0.79709026  0.555      -0.4406645 ]
#  [-0.3599013  -0.63565744 -0.70251352]]

Panda는 모든 데이터 유형을 결측값으로 변환하는 옵션을 도입했습니다.

np.isnan()기능이 일부 데이터 유형과 호환되지 않습니다.

>>> import numpy as np
>>> values = [np.nan, "x", "y"]
>>> np.isnan(values)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

pd.isna() ★★★★★★★★★★★★★★★★★」pd.notna()기능은 많은 데이터 유형과 호환되며 팬더가 도입합니다.pd.NA 추가:

>>> import numpy as np
>>> import pandas as pd

>>> values = pd.Series([np.nan, "x", "y"])
>>> values
0    NaN
1      x
2      y
dtype: object
>>> values.loc[pd.isna(values)]
0    NaN
dtype: object
>>> values.loc[pd.isna(values)] = pd.NA
>>> values.loc[pd.isna(values)]
0    <NA>
dtype: object
>>> values
0    <NA>
1       x
2       y
dtype: object

#
# using map with lambda, or a list comprehension
#

>>> values = [np.nan, "x", "y"]
>>> list(map(lambda x: pd.NA if pd.isna(x) else x, values))
[<NA>, 'x', 'y']
>>> [pd.NA if pd.isna(x) else x for x in values]
[<NA>, 'x', 'y']

가장 간단한 방법은 다음과 같습니다.

numpy.nan_to_num(x)

문서: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html

언급URL : https://stackoverflow.com/questions/11620914/how-do-i-remove-nan-values-from-a-numpy-array

반응형