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

Polars中如何正确将十六进制字符串列转换为uint64类型

Polars中十六进制字符串转UInt64的正确实现

问题场景

在Kaggle美国运通违约预测竞赛的公开存储优化方案中,常用操作是将长十六进制格式的ID字符串截取后,按16进制规则解析为uint64类型,大幅降低列存储空间。在Polars中实现该逻辑时通常会遇到两类异常:

  • 用map_elements封装Python原生int(x,16)逻辑,返回结果和正确值接近但末尾数字存在偏差
  • 直接截取字符串后调用cast(pl.UInt64)触发转换错误,传入strict=False时返回空值

错误原因

  • 精度丢失:使用map_elements时如果未显式指定返回类型,Polars会默认将Python函数返回值推断为float64类型。float64仅能精确表示小于2^53的整数,uint64取值范围的大整数会被截断,导致末尾数字错误。
  • 解析规则不匹配:Polars默认的字符串转整数逻辑按十进制规则解析,无法识别十六进制包含的a-f字符,因此直接cast会报错。

正确实现

推荐方案(原生高性能,无精度问题)

直接使用Polars字符串命名空间下的整数解析方法,指定16进制解析规则,计算全程在Rust层运行,性能是Python层map_elements的10~100倍,结果完全匹配Python原生计算值:

import polars as pl

strings = [
    "0000099d6bd597052cdcda90ffabf56573fe9d7c79be5fbac11a8ed792feb62a",
    "00000fd6641609c6ece5454664794f0340ad84dddce9a267a310b5ae68e9d8e5",
]

df = pl.DataFrame({"id": strings})

result = df.with_columns(
    pl.col("id")
      .str.slice(-16) # 截取最后16位十六进制字符,对应64bit长度
      .str.to_integer(base=16) # 指定按16进制规则解析整数
      .cast(pl.UInt64) # 显式转换为无符号64位整数
      .alias("parsed_uint64")
)

print(result["parsed_uint64"].to_list())
# 输出: [13914591055249847850, 11750091188498716901],与Python原生计算结果完全一致

旧版本兼容方案

如果使用的Polars版本未提供str.to_integer方法,可以通过二进制解码+类型重解释实现:

result = df.with_columns(
    pl.col("id")
      .str.slice(-16)
      .str.decode("hex") # 将十六进制字符串解码为原始二进制
      .bin.reinterpret(dtype=pl.UInt64, endianness="big") # 按大端序重解释为uint64
      .alias("parsed_uint64")
)

注意:十六进制字符串的字节序为大端序,调用bin.reinterpret时必须显式指定endianness="big",否则会得到字节序反转的错误结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:57:21