Python 避免在 Pandas 数据框中除以零

问题描述

很抱歉之前有人问过这个问题,但我无法让这些解决方案对我有用(我是使用 Python 的原生 MATLAB 用户)。

我有一个数据框,我在其中取一个 df 的前 7 列的行均值并将其除以另一个。但是,此数据集中有许多零,我想用零替换零除法错误(因为这对我很有意义)而不是自然返回的 nan(因为我正在实施它)。

到目前为止我的代码

col_ind = list(range(0,7))
df.iloc[:,col_ind].mean(axis=1)/other.iloc[:,col_ind].mean(axis=1)

这里,如果 other = 0,则返回 nan,但如果 df = 0,则返回 0。我尝试了很多建议的解决方案,但似乎都没有注册。例如:

def foo(x,y):
    try:
        return x/y
    except ZeroDivisionError:
        return 0

foo(df.iloc[:,col_ind].mean(axis1),other.iloc[:,col_ind].mean(axis=1))

然而,这在不使用定义的 foo 的情况下返回相同的值。我怀疑这是因为我在操作系列而不是单个值,但我不确定也不知道如何解决它。这些数据帧中也有实际的 nan。任何帮助表示赞赏。

解决方法

您可以使用 np.where 有条件地将其作为矢量化计算。

import numpy as np

df = pd.DataFrame(data=np.concatenate([np.random.randint(1,10,(10,7)),np.random.randint(0,3,1))],axis=1),columns=[f"col_{i}" for i in range(7)]+["div"])

np.where(df["div"].gt(0),(df.loc[:,[c for c in df.columns if "col" in c]].mean(axis=1) / df["div"]),0)
,

不清楚您使用的是哪个版本,我不知道该行为是否与版本相关,但在 Python 3.8.5 / Pandas 1.2.4 中,数据帧/系列中的 0 / 0 将评估为NaN,而非零 / 0 将评估为 inf。两者都不会引发错误,因此 try/except 将无法捕获任何内容。

>>> import pandas as pd
>>> import numpy as np
>>> x = pd.DataFrame({'a': [0,1,2],'b': [0,2]})
>>> x

   a  b
0  0  0
1  1  0
2  2  2

>>> x.a / x.b
0    NaN
1    inf
2    1.0
dtype: float64

您可以使用 fillna() 方法替换 Pandas DataFrame 或 Series 中的 NaN 值,并且您可以使用标准 replace() 替换 inf:

>>> (x.a / x.b).replace(np.inf,np.nan)
0    NaN
1    NaN
2    1.0
dtype: float64

>>> (x.a / x.b).replace(np.inf,np.nan).fillna(0)
0    0.0
1    0.0
2    1.0
dtype: float64

(注意:负值除以零将计算为 -inf,需要单独替换。)

,

您可以在计算后使用 df.fillna(0)

替换 nan