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

Polars中Categorical与Enum类型内存占用及优化、转换问题问询

Polars分类/Enum列内存占用问题解答

内存大小是否准确?

准确。Polars的Categorical和Enum列默认使用int32类型存储类别索引,不管实际类别数量多少,底层数组的类型都是int32,因此estimated_size()返回的内存占用和同长度int32列一致。shrink_to_fit()仅用于清理类别字典中的冗余条目,不会改变底层索引的整数类型,所以无法降低内存占用。

三个疑问的解答

1. 能否减少成员数量少的分类类型的内存占用?

可以。你可以在创建Categorical/Enum列时,指定更小的整数类型作为索引存储类型:

  • 对于Categorical列,创建时通过dtype参数指定更小的无符号整数类型,比如类别数≤255用pl.UInt8,≤65535用pl.UInt16:
    # 示例:将整数列转为用UInt8存储索引的Categorical
    df = df.with_columns(pl.col("cat_col").cast(pl.Categorical(dtype=pl.UInt8)))
    
  • Enum列同样支持该参数,因为Polars的Enum是基于Categorical实现的:
    # 示例:创建基于UInt8的Enum列
    MyEnum = pl.Enum(["a", "b", "c", "d"], dtype=pl.UInt8)
    df = df.with_columns(pl.col("enum_col").cast(MyEnum))
    

2. 有无更优方法将整数ID转换为分类类型?

直接将整数ID转为Categorical/Enum即可,无需额外处理。如果整数ID的范围很小,指定对应小整数类型的Categorical是最优方案,既避免了字符串转换的开销,又能最大化节省内存:

# 直接转换整数列为小索引类型的Categorical
df = df.with_columns(pl.col("int_id").cast(pl.Categorical(dtype=pl.UInt8)))

如果整数ID对应的是固定枚举值,也可以直接定义Enum类型后转换,类型安全性更高:

StatusEnum = pl.Enum([0, 1, 2, 3], dtype=pl.UInt8)
df = df.with_columns(pl.col("status").cast(StatusEnum))

3. 是否需先转换为字符串?

不需要。直接转换整数ID为Categorical/Enum是更高效的方式:

  • 内存上:不用存储字符串,仅存储小整数索引,内存占用远低于字符串列。
  • 性能上:避免了字符串解析、哈希等额外开销,转换和后续操作速度更快。
    只有当你的类别逻辑依赖字符串标识(比如需要将整数ID映射为对应的字符串名称)时,才需要先将整数转为字符串再处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:20:05