パンダのデータフレームから無限の値をドロップしますか?


219

nansとinf / -infの値をリセットせずにpandas DataFrameから削除する最も簡単な方法は何mode.use_inf_as_nullですか?私が使用できるようにしたいと思いますsubsethowの議論をdropnaしている場合を除き、inf同様に、不足していると考えられた値:

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

これは可能ですか?欠損値の定義dropnaに含めるように指示する方法はありinfますか?

回答:


416

最も簡単な方法は、最初replaceにNaNに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

同じ方法がシリーズでも機能します。


2
inf値を事前定義されたものintなどに「交換」するにはどうすればよいですか0特定の列でですか?
3kstc 2018

4
@ 3kstcを使用します.replace(..., 0)。ただ列でアップデートを行うには、これらの列は、IEdf[cols] = df[cols].replace(..., 0)
アンディ・ヘイデン

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

もちろん、次のinfようにNaN永続的に扱うように設定できます。

pd.set_option('use_inf_as_na', True)

古いバージョンの場合は、 use_inf_as_naてくださいuse_inf_as_null


6
これは最も読みやすい解答であり、元の質問の(精神ではなく)書面に違反している場合でも、結果として最良です。
ijoseph 2017年

2
(少なくとも)0.24以降のパンダ:use_inf_as_null推奨されておらず、将来のバージョンで削除される予定です。use_inf_as_na代わりに使用してください。回答を追加/更新しますか?
ホーコン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
Python 2.7以降では、dictの理解がサポートされています:{v: lst for v in cols}
Aryeh Leib Taurog、2015

4

あなたは使うことができpd.DataFrame.masknp.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.