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

如何实现无需指定全部值的DataFrame自定义排序?

自定义部分值排序,其余行保留原顺序

我需要对DataFrame的cat列排序,要求先显示economics,再显示library,剩下的行保持原DataFrame里的顺序,不需要指定所有类别值。

示例数据

import pandas as pd
import numpy as np

order = ["economics","library"]

df = pd.DataFrame({
    "cat": ["library", "economics", "science", np.NaN]
})

期望输出

cat
1  economics
0  library
2  science
3       NaN

原尝试代码(存在语法错误与逻辑漏洞)

# 原代码的语法错误:lambda定义格式错误,且未处理不在order中的值
df.sort_values("cat", key=lambda column: column.map(lambda x: order.index(x)))

问题说明:当x不在order列表中(比如science、NaN),order.index(x)会直接抛出ValueError,无法完成排序。


正确解法

方法1:映射排序键+保留原索引(推荐)

通过自定义排序键,将指定类别映射为优先级高的数字,其余类别映射为统一的高优先级数字,同时结合原索引确保非指定类别保留原顺序:

# 生成排序键:指定类别按order顺序取索引,其余设为order长度(确保排在后面),NaN也统一处理
df_sorted = (
    df.assign(
        sort_key=df["cat"].map(lambda x: order.index(x) if x in order else len(order)).fillna(len(order)),
        original_idx=df.index
    )
    .sort_values(by=["sort_key", "original_idx"])
    .drop(columns=["sort_key", "original_idx"])
)

print(df_sorted)

输出结果完全符合需求:指定类别按order顺序排列,其余行严格保留原DataFrame的出现顺序。

方法2:利用Categorical类型

借助Pandas的Categorical类型定义有序类别,再基于类别码排序:

# 基于order创建有序类别,不在order中的值会被标记为-1,填充为order长度确保排在后面
df_sorted = df.sort_values(
    by="cat",
    key=lambda col: pd.Categorical(col, categories=order, ordered=True).codes.fillna(len(order))
)

这种方式更简洁,但如果需要严格保留非指定类别的原顺序,还是需要结合原索引排序(同方法1的逻辑)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:55:14