You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyArrow Decimal128精度处理:乘法后类型转换报错求助

PyArrow Decimal128货币计算:精度与舍入问题求解

刚接触PyArrow,若有常识疏漏请见谅。

正在更新项目以优化货币计算,核心场景是货币金额乘以百分比(比如9.94 * 0.04)。此前用pandas v1.4.x将货币值存为float,因未统一舍入规则引发诸多问题——以上述例子为例,希望通过常规两位小数舍入得到0.40。

原本打算全面改用decimal.Decimal,后来发现PyArrow内置的decimal128与pandas兼容性更好,但现在遇到两个核心问题:

  • 频繁触发异常:

    pyarrow.lib.ArrowInvalid: Rescaling Decimal128 value would cause data loss

  • 精度变化不符合预期:比如某列 dtype 为pa.decimal128(12,2),执行df['Pay Rate'] * decimal.Decimal('0.04')后,结果类型变为pa.decimal128(15,4)(推测是合并了两个运算对象的精度,逻辑合理但不符合需求);若直接乘0.04,结果类型会变成double[pyarrow]。

我需要最终列类型为decimal128(12,2),尝试执行df['my_col'] = df['my_col'].astype(pd.ArrowDtype(pa.decimal128(12,2)))时,有时会触发上述数据丢失异常。我理解这是因为直接截断小数位导致数据丢失,但实际需求是先四舍五入,再截断小数位。

是否有遗漏的参数或函数可以实现这一需求?

示例代码:

import pandas as pd
import pyarrow as pa
from decimal import Decimal

data = {'col1': {0: Decimal('39.60'), 1: Decimal('39.60'), 2: Decimal('21.60'), 3: Decimal('7.20'), 4: Decimal('18.00'), 5: Decimal('18.00'), 6: Decimal('72.00'), 7: Decimal('30.60'), 8: Decimal('36.00'), 9: Decimal('41.40')}, 'col2': {0: Decimal('0.98'), 1: Decimal('1.00'), 2: Decimal('0.97'), 3: Decimal('0.46'), 4: Decimal('0.52'), 5: Decimal('1.00'), 6: Decimal('1.00'), 7: Decimal('1.00'), 8: Decimal('1.00'), 9: Decimal('1.00')}}
df = pd.DataFrame(data,dtype=pd.ArrowDtype(pa.decimal128(12, 2)))
df['col3'] = df['col1'] * df['col2']
# df['col3'] 的 dtype 为 decimal128(25,4)
df['col3'].astype(pd.ArrowDtype(pa.decimal128(12, 2)))
# 触发异常

内容的提问来源于stack exchange,提问作者scotscotmcc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 22:03:15