在 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
)。要避免无限值,请使用divide
和replace
,例如
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 列划分中的零的主要内容,如果未能解决你的问题,请参考以下文章