如何基于From与To列关联关系对Pandas DataFrame按姓名排序?
按姓名分组排序Pandas DataFrame为路径序列
原始数据
现有如下Pandas DataFrame:
| Name | From | To | Final |
|---|---|---|---|
| Tony | C | D | D |
| Tony | B | C | D |
| Tony | A | D | |
| Tony | A | B | D |
| Mark | A | C | |
| Mark | A | B | C |
| Mark | B | C | C |
需求说明
Tony的数据排序不符合要求,Mark的数据是正确的标准格式,需满足:
- 每组以
From列为空值的行开头 - 最后一行的
To值与Final值一致 - 每行的
To值与下一行的From值完全匹配
需要按Name分组,将每组数据重新排序为上述标准序列。
解决方案
通过groupby结合自定义排序函数实现路径序列的构建:
代码实现
import pandas as pd # 构建原始DataFrame data = [ ["Tony", "C", "D", "D"], ["Tony", "B", "C", "D"], ["Tony", "", "A", "D"], ["Tony", "A", "B", "D"], ["Mark", "", "A", "C"], ["Mark", "A", "B", "C"], ["Mark", "B", "C", "C"], ] df = pd.DataFrame(data, columns=["Name", "From", "To", "Final"]) def sort_group(group): # 建立From到对应行的映射 from_map = group.set_index("From")["To"].to_dict() # 定位起始行(From为空) start_row = group[group["From"] == ""].iloc[0] sorted_rows = [start_row] current_to = start_row["To"] final_val = start_row["Final"] # 按链式关系依次查找后续行 while current_to != final_val: next_row = group[group["From"] == current_to].iloc[0] sorted_rows.append(next_row) current_to = next_row["To"] return pd.DataFrame(sorted_rows) # 分组排序并重置索引 sorted_df = df.groupby("Name", group_keys=False).apply(sort_group).reset_index(drop=True)
排序后结果
运行代码后得到的sorted_df如下:
| Name | From | To | Final |
|---|---|---|---|
| Mark | A | C | |
| Mark | A | B | C |
| Mark | B | C | C |
| Tony | A | D | |
| Tony | A | B | D |
| Tony | B | C | D |
| Tony | C | D | D |
逻辑说明
- 对每个姓名分组,先构建
From到To的映射表,用于快速定位下一个节点 - 找到分组中
From为空的起始行,作为序列的第一个元素 - 从起始行的
To值出发,循环查找From等于该值的行,加入序列,直到当前行的To值与Final值一致 - 将所有分组排序后的结果拼接,得到最终的有序DataFrame
内容的提问来源于stack exchange,提问作者lakadibo
相关产品推荐
相关产品推荐

