在不重置的情况下从 a中删除nan
和inf
/-inf
值的最快/最简单的方法是什么?pandas.DataFrame
mode.use_inf_as_null
我希望能够使用 的subset
和how
参数,但被认为缺失dropna
的值除外,例如:inf
df.dropna(subset=["col1", "col2"], how="all", with_inf=True)
这可能吗?有没有办法告诉dropna
它包含inf
在缺失值的定义中?
最简单的方法是首先将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
同样的方法也适用于系列。
使用选项上下文,无需永久设置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
.
使用(快速简单):
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
.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
上述解决方案将修改inf
不在目标列中的 s。为了解决这个问题,
lst = [np.inf, -np.inf]
to_replace = {v: lst for v in ['col1', 'col2']}
df.replace(to_replace, np.nan)
另一个解决方案是使用该isin
方法。使用它来确定每个值是无限还是缺失,然后链接该all
方法以确定行中的所有值是无限还是缺失。
最后,使用该结果的否定来通过布尔索引选择不具有所有无限或缺失值的行。
all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]
您可以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
要删除两者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
刚刚偶然发现这一行,我发现一行没有替换或 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
。
与这里的其他答案不同,这一行代码对我有用。
import numpy as np
df= df[df['required_column_name']!= np.inf]