Polars(v1.5.0)中Decimal列与整数相乘精度翻倍的问题咨询
在Polars中避免Decimal与整数相乘时Scale翻倍的方法
解决方法
方法1:将整数列转换为scale=0的Decimal后再相乘
把整数列a显式转换为scale=0的Decimal类型,这样相乘时结果的scale就是原Decimal列的scale(原scale + 0),不会翻倍:
df.with_columns( pl.col("c", "d").mul(pl.col("a").cast(pl.Decimal(scale=0))) )
执行后结果结构:
shape: (2, 4) ┌─────┬──────────────┬──────────────┬──────────────┐ │ a ┆ b ┆ c ┆ d │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ decimal[*,2] ┆ decimal[*,3] ┆ decimal[*,2] │ ╞═════╪══════════════╪══════════════╪══════════════╡ │ 1 ┆ 3.45 ┆ 2.113 ┆ 1.10 │ │ 2 ┆ 4.73 ┆ 8.426 ┆ 6.02 │ └─────┴──────────────┴──────────────┴──────────────┘
方法2:相乘后显式转换回原scale
如果已完成相乘操作,可通过cast指定原列的scale来修正结果:
df.with_columns( pl.col("c").mul(pl.col("a")).cast(pl.Decimal(scale=3)).alias("c"), pl.col("d").mul(pl.col("a")).cast(pl.Decimal(scale=2)).alias("d") )
方法3:使用round方法保留原小数位数
直接对相乘结果按原小数位数四舍五入,同时自动匹配原scale:
df.with_columns( pl.col("c").mul(pl.col("a")).round(3).alias("c"), pl.col("d").mul(pl.col("a")).round(2).alias("d") )
问题原因
Polars处理整数与Decimal列相乘时,默认会将整数提升为与原Decimal列具有相同scale的Decimal类型:
- 例如列
c是decimal[*,3],整数a会被转换为decimal[*,3](如1变为1.000) - 根据Decimal乘法规则,结果的scale等于两个操作数的scale之和,因此
3+3=6,最终c列scale变为6 - 同理,列
d原scale为2,整数转换后scale也为2,相乘后scale变为2+2=4
这种行为是为了避免精度丢失,但如果不需要额外小数位数,就需要手动干预类型转换。
内容的提问来源于stack exchange,提问作者fishfin
相关产品推荐
相关产品推荐

