Python 避免在 pandas 数据帧中除以零
Python avoid dividing by zero in pandas dataframe
抱歉之前有人问过这个问题,但我无法让这些解决方案为我工作(我是本地 MATLAB 用户Python)。
我有一个数据框,我在其中取一个 df 的前 7 列的行平均并将其除以另一个。但是,这个数据集中有很多零,我想用零替换零 divion 错误(因为这对我有意义)而不是自然返回的 nan(因为我正在实现它)。
到目前为止我的代码:
col_ind = list(range(0,7))
df.iloc[:,col_ind].mean(axis=1)/other.iloc[:,col_ind].mean(axis=1)
在这里,如果 other = 0,它 returns nan,但如果 df = 0,它 returns 0。我已经尝试了很多建议的解决方案,但 none 似乎注册.例如:
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))
然而,这 returns 没有使用定义的 foo 的相同值。我怀疑这是因为我在操作系列而不是单个值,但我不确定也不知道如何修复它。这些数据框中也有实际的 nans。任何帮助表示赞赏。
您可以使用 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)
您可以在计算后使用 df.fillna(0)
替换 nan
不清楚您使用的是哪个版本,我不知道该行为是否与版本相关,但在 Python 3.8.5 / Pandas 1.2.4 中,a 0 dataframe/series 中的 / 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,需要单独替换。)
抱歉之前有人问过这个问题,但我无法让这些解决方案为我工作(我是本地 MATLAB 用户Python)。
我有一个数据框,我在其中取一个 df 的前 7 列的行平均并将其除以另一个。但是,这个数据集中有很多零,我想用零替换零 divion 错误(因为这对我有意义)而不是自然返回的 nan(因为我正在实现它)。
到目前为止我的代码:
col_ind = list(range(0,7))
df.iloc[:,col_ind].mean(axis=1)/other.iloc[:,col_ind].mean(axis=1)
在这里,如果 other = 0,它 returns nan,但如果 df = 0,它 returns 0。我已经尝试了很多建议的解决方案,但 none 似乎注册.例如:
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))
然而,这 returns 没有使用定义的 foo 的相同值。我怀疑这是因为我在操作系列而不是单个值,但我不确定也不知道如何修复它。这些数据框中也有实际的 nans。任何帮助表示赞赏。
您可以使用 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)
您可以在计算后使用 df.fillna(0)
替换nan
不清楚您使用的是哪个版本,我不知道该行为是否与版本相关,但在 Python 3.8.5 / Pandas 1.2.4 中,a 0 dataframe/series 中的 / 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()
:
>>> (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,需要单独替换。)