从pandas中的数据帧中删除无限值?

189 python numpy scipy pandas

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

df.dropna(subset=["col1", "col2"], how="all", with_inf=True)
Run Code Online (Sandbox Code Playgroud)

这可能吗?有没有办法告诉dropnainf在其缺失值的定义中包含哪些内容?

And*_*den 348

最简单的方法是首先replace向NaN发送信息:

df.replace([np.inf, -np.inf], np.nan)
Run Code Online (Sandbox Code Playgroud)

然后使用dropna:

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

例如:

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
Run Code Online (Sandbox Code Playgroud)

相同的方法适用于系列.

  • @ 3kstc使用`.replace(...,0)`.要在列上更新这些列,即`df [cols] = df [cols] .replace(...,0)` (4认同)
  • 如何在特定列中将 `inf` 值“交换”为预定义的 `int`,例如 `0`? (2认同)
  • 也许值得指定`replace`不能就地工作,所以返回一个新的`DataFrame` (2认同)

ayh*_*han 22

使用选项上下文,无需永久设置即可use_inf_as_na.例如:

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

当然它也可以设置infNaN永久对待use_inf_as_na.

  • 这是最可读的答案,因此是最好的,即使它违反了原始问题的字母(但不是精神). (4认同)
  • Pandas 从(至少)0.24 开始:`use_inf_as_null` 已被弃用,并将在未来版本中删除。请改用 `use_inf_as_na`。添加/更新答案? (2认同)

Ale*_*der 15

这是另一种.loc用于在系列上替换inf的方法:

s.loc[(~np.isfinite(s)) & s.notnull()] = np.nan
Run Code Online (Sandbox Code Playgroud)

所以,回答原来的问题:

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
Run Code Online (Sandbox Code Playgroud)


has*_*2k1 7

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

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

  • python 2.7及更高版本支持dict comprehensions:`{v:lst for v in cols}` (3认同)

Ted*_*rou 6

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

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

all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]
Run Code Online (Sandbox Code Playgroud)


jpp*_*jpp 5

您可以pd.DataFrame.mask与 一起使用np.isinf。您应该首先确保您的数据框系列都是 type floatdropna然后与您现有的逻辑一起使用。

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)

print(df)

       col1      col2
0 -0.441406       NaN
1 -0.321105       NaN
2 -0.412857  2.223047
3 -0.356610  2.513048
Run Code Online (Sandbox Code Playgroud)


Mar*_*hke 5

使用(快速简单):

df = df[np.isfinite(df).all(1)]
Run Code Online (Sandbox Code Playgroud)

该答案基于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='')
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

  • 我收到此错误 - TypeError: ufunc 'isfinite' 不支持输入类型,并且根据转换规则 ''safe'' 无法将输入安全地强制为任何受支持的类型 (2认同)