팬더의 데이터 프레임에서 무한 값을 삭제합니까?


220

재설정하지 않고 팬더 DataFrame에서 nan 및 inf / -inf 값을 삭제하는 가장 빠르고 간단한 방법은 무엇 mode.use_inf_as_null입니까? 누락 된 것으로 간주 되는 값을 제외하고 의 subsethow인수 를 사용할 수 있기를 원합니다 .dropnainf

df.dropna(subset=["col1", "col2"], how="all", with_inf=True)

이게 가능해? 결 측값 정의에 dropna포함시킬 방법이 inf있습니까?

답변:


417

가장 간단한 방법은 먼저 replaceNaN에 infs를 넣는 것입니다 .

df.replace([np.inf, -np.inf], np.nan)

그런 다음 dropna:

df.replace([np.inf, -np.inf], np.nan).dropna(subset=["col1", "col2"], how="all")

예를 들면 다음과 같습니다.

In [11]: df = pd.DataFrame([1, 2, np.inf, -np.inf])

In [12]: df.replace([np.inf, -np.inf], np.nan)
Out[12]:
    0
0   1
1   2
2 NaN
3 NaN

동일한 방법이 Series에서도 작동합니다.


2
어떻게 하나 "교환"는 inf값을 미리 정의에 int같은 0에서 특정 열?
3kstc

4
@ 3kstc 사용 .replace(..., 0). 열을 수행하려면 해당 열을 업데이트하십시오.df[cols] = df[cols].replace(..., 0)
Andy Hayden

3
replace제대로 작동하지 않도록 지정하는 것이 DataFrame
Marco

36

옵션 컨텍스트를 사용하면 영구적으로 설정하지 않고도 가능합니다 use_inf_as_na. 예를 들면 다음과 같습니다.

with pd.option_context('mode.use_inf_as_na', True):
    df = df.dropna(subset=['col1', 'col2'], how='all')

물론 그것은 치료로 설정할 수 있습니다 infNaN영구적으로

pd.set_option('use_inf_as_na', True)

이전 버전의 경우, 교체 use_inf_as_na와 함께 use_inf_as_null.


6
이 질문은 가장 읽기 쉬운 대답이며 원래 질문에 대해서는 그대로 (정신이 아님) 위반하는 경우에도 가장 좋습니다.
ijoseph

2
(최소한) 0.24 현재 팬더는 use_inf_as_null더 이상 사용되지 않으며 향후 버전에서 제거 될 예정입니다. use_inf_as_na대신 사용하십시오 . 답변을 추가 / 업데이트 하시겠습니까?
Håkon T.

1
이것은 inf운영 수준 대신 전역 설정 수준에서 null 로 처리하는 것이 더 좋습니다 . 이를 통해 값을 먼저 대치하는 시간을 절약 할 수 있습니다.
TaoPR

15

다음은 .locSeries에서 inf를 nan으로 바꾸는 데 사용 하는 또 다른 방법입니다 .

s.loc[(~np.isfinite(s)) & s.notnull()] = np.nan

따라서 원래 질문에 대한 답변으로 :

df = pd.DataFrame(np.ones((3, 3)), columns=list('ABC'))

for i in range(3): 
    df.iat[i, i] = np.inf

df
          A         B         C
0       inf  1.000000  1.000000
1  1.000000       inf  1.000000
2  1.000000  1.000000       inf

df.sum()
A    inf
B    inf
C    inf
dtype: float64

df.apply(lambda s: s[np.isfinite(s)].dropna()).sum()
A    2
B    2
C    2
dtype: float64

11

사용 (빠르고 간단 함) :

df = df[np.isfinite(df).all(1)]

이 답변은 다른 질문에 대한 DougR의 답변 을 기반으로 합니다. 예제 코드는 다음과 같습니다.

import pandas as pd
import numpy as np
df=pd.DataFrame([1,2,3,np.nan,4,np.inf,5,-np.inf,6])
print('Input:\n',df,sep='')
df = df[np.isfinite(df).all(1)]
print('\nDropped:\n',df,sep='')

결과:

Input:
    0
0  1.0000
1  2.0000
2  3.0000
3     NaN
4  4.0000
5     inf
6  5.0000
7    -inf
8  6.0000

Dropped:
     0
0  1.0
1  2.0
2  3.0
4  4.0
6  5.0
8  6.0

7

또 다른 해결책은이 isin방법 을 사용하는 것입니다. 이를 사용하여 각 값이 무한한지 또는 없는지 판별 한 후 all메소드를 체인화 하여 행의 모든 값이 무한한지 또는 없는지 판별하십시오 .

마지막으로 부울 인덱싱을 통해 무한 또는 누락 된 값이없는 행을 선택하려면 해당 결과의 부정을 사용하십시오.

all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]

7

위의 솔루션은 inf대상 열에없는을 수정합니다 . 이를 해결하기 위해

lst = [np.inf, -np.inf]
to_replace = {v: lst for v in ['col1', 'col2']}
df.replace(to_replace, np.nan)

3
파이썬 2.7 이상 지원 DICT 함축 :{v: lst for v in cols}
Aryeh Leib Taurog

4

pd.DataFrame.mask와 함께 사용할 수 있습니다 np.isinf. 먼저 데이터 프레임 시리즈가 모두 유형인지 확인해야합니다 float. 그런 다음 dropna기존 논리와 함께 사용 하십시오.

print(df)

       col1      col2
0 -0.441406       inf
1 -0.321105      -inf
2 -0.412857  2.223047
3 -0.356610  2.513048

df = df.mask(np.isinf(df))

print(df)

       col1      col2
0 -0.441406       NaN
1 -0.321105       NaN
2 -0.412857  2.223047
3 -0.356610  2.513048
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.