从熊猫的数据框中删除无限值?


219

从熊猫DataFrame中删除nan和inf / -inf值而不重置的最快/最简单方法是什么mode.use_inf_as_null?我希望能够使用的subsethow参数dropna,但不能使用inf认为缺少的值,例如:

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

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

Answers:


416

最简单的方法是先将replaceinfs改为NaN:

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

4
@ 3kstc使用.replace(..., 0)。要仅对列进行操作,请更新这些列,即df[cols] = df[cols].replace(..., 0)
Andy

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_nause_inf_as_null


6
这是最易读的答案,因此也是最好的答案,即使它在文字上(但在精神上)违反了原始问题。
ijoseph '17

2
从(至少)0.24开始的熊猫use_inf_as_null已被弃用,并将在以后的版本中删除。使用use_inf_as_na代替。添加/更新答案?
哈康T.

1
inf在全局设置级别(而不是操作级别)将其视为空值是一个更好的选择。这可以潜在地节省先输入值的时间。
TaoPR

15

这是.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

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

4

您可以使用pd.DataFrame.masknp.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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.