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

如何从DataFrame中删除naninf-inf值而不重置mode.use_inf_as_null?

我可以告诉dropna在其缺失值的定义中包含inf,以便以下工作吗?

df.dropna(subset=["col1", "col2"], how="all")
473577 次浏览

第一个replace() infs与NaN:

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

然后通过dropna()删除nan:

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

例如:

>>> df = pd.DataFrame({"col1": [1, np.inf, -np.inf], "col2": [2, 3, np.nan]})
>>> df
col1  col2
0   1.0   2.0
1   inf   3.0
2  -inf   NaN


>>> df.replace([np.inf, -np.inf], np.nan, inplace=True)
>>> df
col1  col2
0   1.0   2.0
1   NaN   3.0
2   NaN   NaN


>>> df.dropna(subset=["col1", "col2"], how="all", inplace=True)
>>> df
col1  col2
0   1.0   2.0
1   NaN   3.0

同样的方法也适用于Series

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

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

下面是另一个使用.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

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

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

最后,使用该结果的负数通过布尔索引选择不全是无穷大或缺失值的行。

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

你可以使用pd.DataFrame.masknp.isinf。你应该首先确保你的dataframe系列都是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

使用(快捷简单):

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

使用一个命令同时删除Naninf,请使用

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

只是偶然发现了这一个,我发现了一行没有替换或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,可能需要在列b的名字周围使用回`

与这里的其他答案不同,这一行代码适合我。

import numpy as np
df= df[df['required_column_name']!= np.inf]