Polars窗口聚合函数处理Decimal类型时存在精度错误问题
Polars 1.21.0窗口聚合Decimal类型值被放大100倍的解决方案
在Python 3.10.8搭配Polars 1.21.0时,对Decimal(10,2)类型列使用窗口聚合(over())会出现结果被错误放大100倍的问题,以下是几个可靠的解决方案:
1. 优先升级Polars版本
这个问题属于版本特定的bug,后续发布的Polars版本大概率已经修复了该问题。执行以下命令升级到最新稳定版:
pip install --upgrade polars
升级后重新运行你的窗口聚合代码,即可验证问题是否解决。
2. 保留Decimal精度的兼容处理(不升级版本时)
如果暂时无法升级版本,可通过将Decimal转为整数计算,再转回Decimal的方式规避bug,既保留Decimal的小数精度控制,又避免直接除以100的风险:
import polars as pl pl.DataFrame( { 'People':['John', 'John', 'John', 'John', 'Jane', 'Jane', 'Jane', 'Jane'], 'Balance': [0.00, 10.59, 11.29, 0.00, 12.34, 23.45, 34.56, 45.67] } , schema={'People':pl.String, 'Balance':pl.Decimal(10, 2)} ).with_columns( Bal_max = pl.col("Balance").max(), # 修复后的窗口聚合:转整数计算后转回Decimal Bal_max_person_fixed = (pl.col("Balance").cast(pl.Int64) .max().over("People") .cast(pl.Decimal(10, 2))), Bal_min_person_fixed = (pl.col("Balance").cast(pl.Int64) .min().over("People") .cast(pl.Decimal(10, 2))), Bal_sum_person_fixed = (pl.col("Balance").cast(pl.Int64) .sum().over("People") .cast(pl.Decimal(10, 2))) )
原理:Decimal(10,2)的底层存储是放大100倍的整数,转Int64做聚合不会丢失精度,聚合完成后转回Decimal(10,2)即可得到正确的两位小数结果,比直接除以100更可靠,避免了浮点数运算的潜在精度问题。
3. 临时精度调整方案(慎用)
如果不想转整数,也可以尝试在聚合后强制指定Decimal精度,但该方案依赖版本细节,稳定性不如转整数的方法:
Bal_max_person_fixed = pl.col("Balance").max().over("People").cast(pl.Decimal(10,2))
内容的提问来源于stack exchange,提问作者jpm_phd
相关产品推荐
相关产品推荐

