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

Posted

技术标签:

【中文标题】在 Python 中处理 pandas DataFrames 列划分中的零【英文标题】:handling zeros in pandas DataFrames column divisions in Python 【发布时间】:2013-04-21 02:02:06 【问题描述】:

在 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 执行此操作?

【问题讨论】:

如果你只使用浮点数,你会得到 +/-inf @askewchan:它对我不起作用 - 请参阅编辑 【参考方案1】:

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

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

【讨论】:

我可以只将 df 的一列转换为 float64 而不是整个数据帧吗?请参阅我的编辑。我仍然收到 float64 dtype 的错误 在 0.11 中是; 0.10.1或更早的应该可以工作,你用的是什么版本? 您还在代码库中的任何地方使用np.seterr() 吗? 澄清一下,现在不能用pd.DataFrame.div处理这个吗? 不,那只是广播。这里的问题是如何处理0/0(并将其转换为nan,默认为inf【参考方案2】:

为了完整起见,我想添加以下使用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)

【讨论】:

【参考方案3】:

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

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

见:

Handling division by zero in Pandas calculations dropping infinite values from dataframes in pandas?

【讨论】:

以上是关于在 Python 中处理 pandas DataFrames 列划分中的零的主要内容,如果未能解决你的问题,请参考以下文章

pandas_处理异常值缺失值重复值数据差分

pandas_处理异常值缺失值重复值数据差分

python:根据条件对时间序列数据进行分组或拆分

python pandas.DataFrame选取修改数据最好用.loc,.iloc,.ix

pandas索引操作

pandas dataframe 中的 explode 函数