如何基于指定列值顺序列表重排pandas DataFrame行顺序
问题背景
现有存储文件与对应字段信息的DataFrame df,初始结构如下:
File Field Folder Users.csv Age UserFolder Users.csv Name UserFolder Cars.csv Color CarFolder Cars.csv Model CarFolder
已提前定义好不同文件下Field列的自定义排序规则:
users_col_order = ['Name', 'Age'] cars_col_order = ['Model', 'Color']
需要按照上述规则重排DataFrame行顺序,最终得到如下结果(注意不是按Field的字母序排序):
File Field Folder Users.csv Name UserFolder Users.csv Age UserFolder Cars.csv Model CarFolder Cars.csv Color CarFolder
实现方案
优先使用pandas自带的Categorical类型实现自定义排序,性能和可读性最优,步骤如下:
- 先把分散的排序规则整理为统一的映射字典,方便后续匹配调用:
# 文件对应Field排序规则映射 field_order_map = { "Users.csv": ["Name", "Age"], "Cars.csv": ["Model", "Color"] } # 文件本身的展示顺序映射 file_order = ["Users.csv", "Cars.csv"]
- 将
File和Field列转为带自定义顺序的Categorical类型,pandas排序时会自动按照指定的类别顺序排列,而非默认的字典序:
import pandas as pd # 给File列设置自定义排序顺序 df["File"] = pd.Categorical(df["File"], categories=file_order, ordered=True) # 按File分组,给每个分组内的Field设置对应排序顺序 df["Field"] = df.groupby("File")["Field"].transform( lambda x: pd.Categorical(x, categories=field_order_map[x.name], ordered=True) ) # 排序后重置索引即可得到结果 df_sorted = df.sort_values(by=["File", "Field"]).reset_index(drop=True)
运行后df_sorted的输出和期望结果完全一致。
如果数据量较小,也可以用匹配排序索引的方式实现,逻辑更直观:
# 生成文件排序权重 df["file_weight"] = df["File"].map({f:i for i,f in enumerate(file_order)}) # 生成每个Field在对应规则里的位置权重 df["field_weight"] = df.apply( lambda row: field_order_map[row["File"]].index(row["Field"]), axis=1 ) # 按权重排序后删除辅助列 df_sorted = df.sort_values(by=["file_weight", "field_weight"])\ .drop(columns=["file_weight", "field_weight"])\ .reset_index(drop=True)
注意:数据量超过10万行时优先选择第一种Categorical方案,
apply逐行遍历的性能会明显下降。后续如果需要新增文件类型,只需要在两个映射配置里追加对应规则即可,不需要修改排序逻辑。
内容的提问来源于stack exchange,提问作者Barry
相关产品推荐
相关产品推荐

