python - 如何将圆形应用于两个熊猫列
问题描述
我正在尝试将 pandas 数据框的一列中的值四舍五入到另一列中指定的小数位,如下面的代码所示。
df = pandas.DataFrame({
'price': [14.5732, 145.731, 145.722, 145.021],
'decimal': [4, 3, 2, 2]
})
df['price'] = df.apply(lambda x: round(x.price, x.decimal), axis=1)
但是,这样做会导致以下错误:
> df['price'] = df.apply(lambda x: round(x.price, x.decimal), axis=1)
E TypeError: ('integer argument expected, got float', 'occurred at index 0')
文档看起来好像 round 期望在索引 0 处浮动,但它显然不高兴。将 price 更改为 int 可以修复错误,但这会破坏代码本身的意义。
解决方案
很长一段时间以来,这一直是 pandas 的痛点。当访问单行或沿第一个轴调用 apply 时,dtype 强制会定期发生。该错误消息令人困惑,因为很明显您的十进制系列的 dtype 是整数类型,因此该方法应该接受它round
,但是强制发生在幕后。
您可以同时使用iloc
和进行检查apply
:
>>> df.iloc[0]
price 14.5732
decimal 4.0000
Name: 0, dtype: float64
>>> df.apply(lambda x: x, axis=1)
price decimal
0 14.5732 4.0
1 145.7310 3.0
2 145.7220 2.0
3 145.0210 2.0
更令人沮丧的是,如果您有一个 object dtype 列,则不会强制执行任何操作,因此行为并不是那么容易预测!
>>> df['foo'] = 'bar'
>>> df.iloc[0]
price 14.5732
decimal 4
foo bar
Name: 0, dtype: object
长话短说,它令人困惑且根本不直观。一些解决方法是在 lambda 函数中转换小数点或使用列表推导(可能比应用更快)。
>>> df.apply(lambda x: round(x.price, int(x.decimal)), axis=1)
0 14.5732
1 145.7310
2 145.7200
3 145.0200
dtype: float64
>>> [round(x, y) for x, y in zip(df['price'], df['decimal'])]
[14.5732, 145.731, 145.72, 145.02]
请注意,当以系列显示时,表示不会改变,但值将被四舍五入。
推荐阅读
- vba - 调用从 Delphi ADO 组件调用模块中的 VBA 函数的 MS Access 查询
- laravel - Laravel:在 Model::all() 上将参数设置为模型方法
- python - 在redis中完全删除哈希键的问题
- sql-server - TSQL XML 存在带有命名空间和 IF-ELSE 条件的查询
- docker - 无法使用 docker swarm 运行应用程序,但使用 docker-compose 运行相同
- python - Django Crispy 表单不使用 bootstrap 4 构建 Accordion
- c# - 为什么向量不能延续到其他函数中?
- c++ - 将 exprtk 变量分配为向量成员
- python - {:d} 在 Python 中做了什么?
- android - 如何创建已弃用版本的 Android 虚拟设备