web-dev-qa-db-ja.com

パンダのデータフレームから無限値を落とす?

mode.use_inf_as_nullをリ​​セットせずに、パンダDataFrameからnanおよびinf/-inf値を削除するための最も簡単な方法は何ですか。以下のように、subsetの値が欠落していると見なされる場合を除いて、howdropnaおよびinf引数を使用できるようにします。

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

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

152
user248237

最も簡単な方法は、まず 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

同じ方法がSeriesでも機能します

291
Andy Hayden

オプションコンテキストでは、これはuse_inf_as_nullを恒久的に設定することなく可能です。例えば:

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

pd.set_option('use_inf_as_null', True)でも永続的にinfNaNとして扱うように設定できます。

16
ayhan

これは、Series上で.locを使用して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
15
Alexander

上記の解決策は、ターゲット列にないinfsを変更します。それを直すには、

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

さらに別の解決策はisinメソッドを使うことです。これを使用して、各値が無限または欠落しているかどうかを判別してから、allメソッドを連鎖させて、行内のすべての値が無限または欠落しているかどうかを判別します。

最後に、その結​​果の否定を使用して、すべての無限値または欠損値を持たない行をブール索引付けによって選択します。

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

使用する(速くて簡単):

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

この答えは他の質問の DougR's answer に基づいています。ここでのコード例:

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
4
Markus Dutschke

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
2
jpp