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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:47:02