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

如何修改Polars DataFrame中已有分类列的自定义排序?

修改Polars DataFrame分类列自定义排序的解决方案

问题原因

你遇到的问题核心是Polars的StringCache会缓存首次注册的分类顺序:第一次通过pl.Series(myorder).cast(pl.Categorical)在缓存中注册了["k", "z", "b", "a"]的类别映射,后续再次执行cast(pl.Categorical)时,Polars会直接复用已缓存的映射关系,导致新的排序规则不生效。

解决方案

推荐以下两种可靠的修改方式:

方法1:显式指定分类顺序(推荐,无需依赖缓存)

直接在cast(pl.Categorical)时通过order参数指定新的排序,同时先将原分类列转回字符串类型,确保完全重置类别映射:

# 新的自定义排序
myorder = ["b", "z", "k", "a"]

# 先转回字符串,再重新设置分类并指定顺序
df = df.with_columns(
    pl.col('cats').cast(pl.String).cast(pl.Categorical(order=myorder))
)

print(df.sort(["cats"]))

执行后输出会符合新排序:

shape: (5, 2)
┌──────┬──────┐
│ cats ┆ vals │
│ ---  ┆ ---  │
│ cat  ┆ i64  │
╞══════╪══════╡
│ b    ┆ 3    │
│ z    ┆ 3    │
│ z    ┆ 1    │
│ k    ┆ 2    │
│ a    ┆ 2    │
└──────┴──────┘

方法2:清空StringCache后重新注册

如果需要保留缓存方式,需先清空已有缓存,再重新注册新排序,同时将列转回字符串后再cast:

# 新的自定义排序
myorder = ["b", "z", "k", "a"]

# 清空字符串缓存
pl.StringCache().clear()

with pl.StringCache():
    # 重新注册新的分类顺序
    pl.Series(myorder).cast(pl.Categorical)
    # 先转回字符串再转换为分类,避免复用旧映射
    df = df.with_columns(pl.col('cats').cast(pl.String).cast(pl.Categorical))

print(df.sort(["cats"]))

注意事项

  • Polars 0.18.0及以上版本支持pl.Categorical(order=...)参数,这是更直观且可控的方式,优先使用。
  • 不要直接对已有分类列再次执行cast(pl.Categorical),因为Polars会复用缓存或已有列的类别映射,无法更新排序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:43:21