【问题标题】:Python avoid dividing by zero in pandas dataframePython避免在熊猫数据框中除以零
【发布时间】:2021-04-27 18:01:44
【问题描述】:

抱歉,之前有人问过这个问题,但我无法让这些解决方案为我工作(我是使用 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。任何帮助表示赞赏。

【问题讨论】:

  • 欢迎来到 StackOverflow(和 Python),您能提供更多代码吗?例如,您的 Dataframe df 是什么?

标签: python pandas dataframe divide-by-zero


【解决方案1】:

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

import numpy as np

df = pd.DataFrame(data=np.concatenate([np.random.randint(1,10, (10,7)), np.random.randint(0,3,(10,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)

【讨论】:

  • 谢谢,这似乎奏效了。我不完全确定在.where 上附加了什么.gt。将其返回到我的示例, df["div"] 是 'other' 并且 .gt(0) 返回一个真/假向量,其中 other 为 0 的任何元素都返回一个假。然后,该语句在 other != 0 的情况下进行正常除法,否则返回 0。我以前在玩 np.where 但不确定为什么这个有效。对于那些感兴趣的人,我更正的代码:np.where(other.iloc[:,col_ind].mean(axis=1).gt(0), (df.iloc[:,col_ind].mean(axis=1) / other.iloc[:,col_ind].mean(axis=1)), 0)
  • 我可能应该使用.ne(0) 来消除除数为正的假设
【解决方案2】:

不清楚您使用的是哪个版本,我不知道行为是否取决于版本,但在 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, 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,需要单独替换。)

【讨论】:

  • 你是对的,我误读了我的命令返回的内容,谢谢。
【解决方案3】:

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

【讨论】:

  • 数据集已经有实际的 nan 值,不幸的是需要保留
猜你喜欢
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
  • 2022-01-24
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多