基于before_id匹配规则调整pandas DataFrame行位置的方案咨询
实现思路
你要实现的行重排本质是按节点从属关系排序,完全可以用pandas实现,不需要脱离框架。你之前用reindex不生效的核心原因是:单行Series调用reindex仅会调整当前行的索引顺序,不会修改原DataFrame的整体行排序,且遍历过程中直接修改DataFrame索引会导致后续定位逻辑错乱。
正确实现逻辑参考:
- 先把数据转换为邻接表结构,记录每个node_id对应的所有子节点(即before_id等于该node_id的行)
- 筛选出所有根节点(before_id为空的行),保留原表中的出现顺序
- 对根节点做深度优先遍历,依次收集节点ID,即可得到符合「子节点跟在父节点下方」要求的顺序
- 最后用收集到的ID顺序对原DataFrame重排即可
可运行代码
import pandas as pd import io client_data = """node_id,option,before_id 1,A, 5,A,4 4,C,1 6,A, 2,A,1 7,C,6 """ # 读取数据,把before_id列转为可空整数类型 df = pd.read_csv(io.StringIO(client_data), skipinitialspace=True) df['before_id'] = df['before_id'].astype('Int64') # 构建邻接表:key为父节点node_id,value为对应子节点node_id列表 adj_map = {} for _, row in df.iterrows(): parent_id = row['before_id'] if pd.notna(parent_id): adj_map.setdefault(parent_id, []).append(row['node_id']) # 提取所有根节点(无前置id的行),保留原表出现顺序 root_nodes = df[df['before_id'].isna()]['node_id'].tolist() # 深度优先遍历生成目标顺序 sorted_ids = [] def dfs(node_id): sorted_ids.append(node_id) # 递归遍历当前节点的所有子节点 if node_id in adj_map: for child_id in adj_map[node_id]: dfs(child_id) for root in root_nodes: dfs(root) # 按生成的顺序重排DataFrame result_df = df.set_index('node_id').loc[sorted_ids].reset_index() # 输出到csv result_df.to_csv('./result3.csv', index=False)
输出结果
运行上述代码得到的排序结果如下:
node_id,option,before_id 1,A, 4,C,1 5,A,4 2,A,1 6,A, 7,C,6
你给出的预期输出中出现的8,C,2属于测试数据笔误,补充对应数据后代码可自动适配多层级排序。
内容的提问来源于stack exchange,提问作者okkotsu
相关产品推荐
相关产品推荐

