繁体   English   中英

在 Python 中处理 pandas DataFrames 列划分中的零

[英]handling zeros in pandas DataFrames column divisions in Python

在 Python 中将 pandas DataFrame 列彼此分开时,处理零分母的最佳方法是什么? 例如:

df = pandas.DataFrame({"a": [1, 2, 0, 1, 5], "b": [0, 10, 20, 30, 50]})
df.a / df.b  # yields error

我希望将分母为零的比率注册为 NA ( numpy.nan )。 如何在熊猫中有效地做到这一点?

转换为float64不适用于列级别:

In [29]: df
Out[29]: 
   a   b
0  1   0
1  2  10
2  0  20
3  1  30
4  5  50

In [30]: df["a"].astype("float64") / df["b"].astype("float64")
...

FloatingPointError: divide by zero encountered in divide

如何仅针对特定列而不是整个 df 执行此操作?

你需要在浮点数中工作,否则你会有整数除法,可能不是你想要的

In [12]: df = pandas.DataFrame({"a": [1, 2, 0, 1, 5], 
                                "b": [0, 10, 20, 30, 50]}).astype('float64')

In [13]: df
Out[13]: 
   a   b
0  1   0
1  2  10
2  0  20
3  1  30
4  5  50

In [14]: df.dtypes
Out[14]: 
a    float64
b    float64
dtype: object

这是一种方法

In [15]: x = df.a/df.b

In [16]: x
Out[16]: 
0         inf
1    0.200000
2    0.000000
3    0.033333
4    0.100000
dtype: float64

In [17]: x[np.isinf(x)] = np.nan

In [18]: x
Out[18]: 
0         NaN
1    0.200000
2    0.000000
3    0.033333
4    0.100000
dtype: float64

这是另一种方式

In [20]: df.a/df.b.replace({ 0 : np.nan })
Out[20]: 
0         NaN
1    0.200000
2    0.000000
3    0.033333
4    0.100000
dtype: float64

为了完整起见,我想添加以下使用DataFrame.apply的划分方式,例如:

df.loc[:, 'c'] = df.apply(div('a', 'b'), axis=1)

在全:

In [1]:
df = pd.DataFrame({"a": [1, 2, 0, 1, 5, 0], "b": [0, 10, 20, 30, 50, 0]}).astype('float64')

def div(numerator, denominator):
  return lambda row: 0.0 if row[denominator] == 0 else float(row[numerator]/row[denominator])

df.loc[:, 'c'] = df.apply(div('a', 'b'), axis=1)

Out[1]:
      a     b         c
0   1.0   0.0  0.000000
1   2.0  10.0  0.200000
2   0.0  20.0  0.000000
3   1.0  30.0  0.033333
4   5.0  50.0  0.100000
5   0.0   0.0  0.000000

此解决方案比Jeff提出的解决方案慢:

df.loc[:, 'c'] = df.apply(div('a', 'b'), axis=1)
# 1.27 ms ± 113 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

df.loc[:, 'c'] = df.a/df.b.replace({ 0 : np.inf })
# 651 µs ± 44.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

通常在 Panda 中除以零时,该值设置为无限( np.inf )。 为避免无限值,请使用dividereplace ,例如

df['one'].div(df['two']).replace(np.inf, 0)

看:

为了说明 pandas 对不同 dtype 的列的不同行为,请注意,pandas 通过返回 inf 的结果支持对具有 numeric dtype 的列(例如 float 和 int64)进行除以零,但对于 object 类型的列,它会引发ZeroDivisionError 异常。

有关示例,请参见我对相关问题的回答

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM