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
相关产品推荐
相关产品推荐

