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

Polars如何无损精度向下转换浮点数据类型?

Polars 无损向下转换浮点列数据类型的方法

首先明确:你观察到的差异本质是 Polars的shrink_dtype与pandasdowncast="float"的逻辑不同:

  • polars.Expr.shrink_dtype是直接强制将float64转换为float32,不会检查值是否能被目标类型精确表示,所以像2.7这种无法用二进制浮点精确存储的数值,转换后会出现精度偏差。
  • pandas的pd.to_numeric(downcast="float")会先验证每个值是否能被float32精确表示,仅对能无损转换的值进行类型压缩,无法精确表示的会保留float64类型。

在Polars中,你可以通过手动验证精度+条件转换的方式实现类似pandas的无损向下转换逻辑,具体实现如下:

实现代码示例

import polars as pl

# 示例数据
df = pl.DataFrame({
    "float_col": [2.0, 3.5, 2.7, 1.0000000001]
})

# 自定义无损转换逻辑:仅保留能被float32精确表示的值,其余保留float64
def safe_downcast_float(col: str) -> pl.Expr:
    casted = pl.col(col).cast(pl.Float32)
    return pl.when(casted.cast(pl.Float64) == pl.col(col))
             .then(casted)
             .otherwise(pl.col(col))

# 应用转换
df_optimized = df.with_columns(safe_downcast_float("float_col"))

# 查看结果和类型
print(df_optimized)
print(df_optimized.schema)

逻辑说明

  1. 先将列转换为float32,再转换回float64与原数值比较:
    • 如果相等,说明该值可以被float32精确存储,保留转换后的float32类型
    • 如果不相等,说明存在精度损失,保留原float64类型
  2. 这种方法会生成混合类型的列(部分值是float32,部分是float64),Polars会自动将列的类型标记为pl.Float64(取所有值的公共超类型),但实际存储中会对可压缩的值使用float32,达到类似pandas的无损压缩效果。

如果你需要强制让整个列统一为float32且接受部分值的精度损失,直接用pl.col(col).cast(pl.Float32)即可;如果要严格无损,就用上述条件转换的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:26:04