如何基于自定义顺序对Polars DataFrame列值进行排序?
解决Polars DataFrame按自定义顺序排序的问题
你之前的StringCache方法没生效,核心原因是没有给Categorical类型指定自定义的类别顺序,Polars默认会按字符串的自然字典序处理分类,所以达不到你要的排序效果。下面提供两种可靠的解决方式:
方法1:使用带自定义顺序的Categorical类型
直接将目标列转换为指定了类别顺序的Categorical类型,再设置按物理顺序排序,最后对该列排序即可:
import polars as pl df = pl.DataFrame( { "a": [1, 2, None], "b": [6.0, 5.0, 4.0], "c": ["a", "c", "b"], } ) sort_list = ['c', 'b', 'a'] # 显式指定categories确保排序顺序完全匹配需求,同时设置物理排序规则 df_sorted = df.with_columns( pl.col("c").cast(pl.Categorical(categories=sort_list)).cat.set_ordering("physical") ).sort("c") print(df_sorted)
输出结果和你的预期完全一致:
shape: (3, 3) ┌──────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ cat │ ╞══════╪═════╪═════╡ │ 2 ┆ 5.0 ┆ c │ │ null ┆ 4.0 ┆ b │ │ 1 ┆ 6.0 ┆ a │ └──────┴─────┴─────┘
如果不需要保留Categorical类型,排序后可以再转回到字符串:
df_sorted = df_sorted.with_columns(pl.col("c").cast(pl.String))
方法2:生成临时排序键(无需修改原列类型)
如果不想改变原列的数据类型,可以通过映射生成一个临时的排序键,按键排序后删除该临时列:
df_sorted = df.with_columns( # 用sort_list的索引作为排序依据 sort_key=pl.col("c").map_elements(lambda x: sort_list.index(x), return_dtype=pl.Int32) ).sort("sort_key").drop("sort_key") print(df_sorted)
这种方法的优势是不会修改原列的类型,适合需要保持原数据结构的场景。
你之前代码的问题分析
你之前的代码中,只是单独把sort_list转成了Categorical,但并没有将这个顺序关联到DataFrame的c列上;同时也没有设置set_ordering("physical"),所以Polars还是默认按字典序处理c列的排序,自然得不到预期结果。
内容的提问来源于stack exchange,提问作者buggsbunny4
相关产品推荐
相关产品推荐

