如何在Pandas中按自定义关联规则排序行并处理同日期场景?
用Python/Pandas实现值转换日志的拓扑排序
原始样本数据
id nv ov date 1 1 0 01/02/2023 1 2 1 01/02/2023 1 5 4 01/03/2023 1 1 3 01/02/2023 1 4 1 01/02/2023 1 3 2 01/02/2023 1 6 5 01/03/2023 1 7 6 01/04/2023 1 7 7 01/04/2023
字段说明:
nv:新值(new value)ov:旧值(old value)
排序规则
ov为null(或样本中的0)的行必须排在最前面- 排序后需满足:前一行的
nv等于当前行的ov - 当有多个匹配项时,选择能覆盖所有转换记录的路径(例如(1,0)之后优先选(2,1)而非(4,1))
- 同一日期内的多条记录需遵循上述转换逻辑排序
Pandas实现方案
可以通过构建转换拓扑图+深度优先遍历的方式实现,代码如下:
import pandas as pd # 1. 加载原始数据 data = [ [1, 1, 0, "01/02/2023"], [1, 2, 1, "01/02/2023"], [1, 5, 4, "01/03/2023"], [1, 1, 3, "01/02/2023"], [1, 4, 1, "01/02/2023"], [1, 3, 2, "01/02/2023"], [1, 6, 5, "01/03/2023"], [1, 7, 6, "01/04/2023"], [1, 7, 7, "01/04/2023"], ] df = pd.DataFrame(data, columns=["id", "nv", "ov", "date"]) # 2. 构建转换映射:按ov分组,先按日期+nv排序保证遍历优先级 df_sorted = df.sort_values(by=["date", "nv"], ignore_index=True) transition_map = df_sorted.groupby("ov")["nv"].apply(list).to_dict() # 3. 深度优先遍历拓扑图,覆盖所有转换路径 visited = set() result_order = [] def dfs(current_nv): if current_nv in transition_map: for nv in transition_map[current_nv]: rows = df_sorted[(df_sorted["ov"] == current_nv) & (df_sorted["nv"] == nv)] for _, row in rows.iterrows(): row_tuple = tuple(row) if row_tuple not in visited: visited.add(row_tuple) result_order.append(row) dfs(nv) # 先处理起始节点(ov=0) start_rows = df_sorted[df_sorted["ov"] == 0] for _, row in start_rows.iterrows(): row_tuple = tuple(row) if row_tuple not in visited: visited.add(row_tuple) result_order.append(row) dfs(row["nv"]) # 处理剩余未访问的节点(比如自循环记录) remaining_rows = df_sorted[~df_sorted.apply(tuple, axis=1).isin(visited)] for _, row in remaining_rows.iterrows(): result_order.append(row) # 4. 生成带排序序号的结果 result_df = pd.DataFrame(result_order).reset_index(drop=True) result_df["rn"] = result_df.index + 1 # 输出结果 print(result_df.to_string(index=False))
预期输出
id nv ov date rn 1 1 0 01/02/2023 1 1 2 1 01/02/2023 2 1 3 2 01/02/2023 3 1 1 3 01/02/2023 4 1 4 1 01/02/2023 5 1 5 4 01/03/2023 6 1 6 5 01/03/2023 7 1 7 6 01/04/2023 8 1 7 7 01/04/2023 9
内容的提问来源于stack exchange,提问作者midoriya007
相关产品推荐
相关产品推荐

