从pandas的数据框中丢弃无限的值?
什么是最快/最简单的方法来从一个pandasDataFrame中删除nan和inf / -inf值,而无需重置mode.use_inf_as_null
? 我希望能够使用subset
和dropna
参数,除了inf
值被认为是缺less的,如:
df.dropna(subset=["col1", "col2"], how="all", with_inf=True)
这可能吗? 有没有办法告诉dropna
将inf
纳入其缺失值的定义中?
最简单的方法是首先replace
infs换成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
同样的方法将适用于一个系列。
这里是另一种使用.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 ABC 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
上述解决scheme将修改不在目标列中的信息。 为了弥补这一点,
lst = [np.inf, -np.inf] to_replace = dict((v, lst) for v in ['col1', 'col2']) df.replace(to_replace, np.nan)
通过选项上下文,可以不用永久设置use_inf_as_null
。 例如:
with pd.option_context('mode.use_inf_as_null', True): df = df.dropna(subset=['col1', 'col2'], how='all')
当然,也可以设置为使用pd.set_option('use_inf_as_null', True)
将inf
永久对待为NaN
。
另一个解决scheme是使用isin
方法。 使用它来确定每个值是无限还是丢失,然后链接all
方法以确定行中的所有值是无限还是丢失。
最后,使用该结果的否定来通过布尔索引来select不具有所有无限值或缺失值的行。
all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns') df[~all_inf_or_nan]