314

在不重置的情况下从 a中删除naninf/-inf值的最快/最简单的方法是什么?pandas.DataFramemode.use_inf_as_null

我希望能够使用 的subsethow参数,但被认为缺失dropna的值除外,例如:inf

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

这可能吗?有没有办法告诉dropna它包含inf在缺失值的定义中?

4

10 回答 10

594

最简单的方法是首先将replace()infs 转换为 NaN:

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

然后使用dropna()

df.replace([np.inf, -np.inf], np.nan, inplace=True) \
    .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, inplace=True)
Out[12]:
    0
0   1
1   2
2 NaN
3 NaN

同样的方法也适用于系列。

于 2013-07-04T21:50:51.893 回答
69

使用选项上下文,无需永久设置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_nause_inf_as_null.

于 2017-08-17T23:10:32.467 回答
19

使用(快速简单):

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
于 2019-03-18T18:41:47.363 回答
17

.loc这是在 Series 上用 nan 替换 inf的另一种方法:

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
于 2016-03-03T21:52:22.923 回答
9

上述解决方案将修改inf不在目标列中的 s。为了解决这个问题,

lst = [np.inf, -np.inf]
to_replace = {v: lst for v in ['col1', 'col2']}
df.replace(to_replace, np.nan)
于 2014-08-10T02:27:01.433 回答
8

另一个解决方案是使用该isin方法。使用它来确定每个值是无限还是缺失,然后链接该all方法以确定行中的所有值是无限还是缺失。

最后,使用该结果的否定来通过布尔索引选择不具有所有无限或缺失值的行。

all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]
于 2017-11-03T18:34:37.670 回答
4

您可以pd.DataFrame.mask使用np.isinf. 您应该首先确保您的数据框系列都是 type 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
于 2018-06-28T15:42:01.363 回答
3

要删除两者Nan,并inf使用单个命令使用

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

如果由于某种原因上述方法对您不起作用,请尝试以下 2 个步骤:

df = df[ ~( df.isnull().any( axis = 1 ) ) ] #to remove nan
df = df[ ~( df.isin( [np.inf, -np.inf]).any(axis =1) )] #to remove inf
于 2021-07-20T16:10:12.803 回答
1

刚刚偶然发现这一行,我发现一行没有替换或 numpy:

df = pd.DataFrame(
    [[1, np.inf],
     [1, -np.inf],
     [1, 2]],
    columns=['a', 'b']
)
df.query("b not in [inf, -inf]")
>>> a  b
 2  1  2.0

对于某些版本pandas,可能需要使用 back 来`围绕列的名称b

于 2021-09-16T16:43:16.527 回答
1

与这里的其他答案不同,这一行代码对我有用。

import numpy as np
df= df[df['required_column_name']!= np.inf]
于 2022-02-01T10:08:21.783 回答