如何基于跨行值修改DataFrame 生成桑基图source/target字段
Pandas处理客户流转数据生成桑基图source/target字段
针对300万条客户阶段记录的处理需求,直接使用Pandas内置向量化操作即可,无需逐行遍历,普通办公设备几秒就能跑完,实现逻辑如下:
- 核心逻辑前提:同一个客户的阶段记录必须按时间先后排序,才能正确匹配下一阶段的position值
- source列直接取当前行的
position字段即可,不需要额外计算 - target列取同一客户按时间排序后,下一条记录的
position值;如果是客户的最后一条记录,填充为定义的退出节点值4
具体实现步骤
- 日期格式转换:原始数据的日期是
日-月-年字符串格式,先转为Pandas内置的datetime类型,避免排序逻辑错误 - 分组排序:按
client_id分组,组内按start_date升序排列,还原每个客户的阶段流转时间线 - 字段计算:通过分组移位
shift(-1)直接取到下一条记录的position,空值统一填充为4 - (可选)顺序还原:如果需要保留原始数据的行顺序,可以提前记录原始行号,计算完成后再还原
性能提示:300万条数据量级下不要使用apply、自定义循环等逐行操作,和内置向量化操作的性能差距会达到百倍以上
可直接运行的代码
import pandas as pd # 替换为你的数据读取逻辑,支持csv、数据库读取等任意方式 df = pd.read_csv("your_customer_data_path.csv") # 【可选步骤】记录原始行号,处理完后可恢复原始数据排列顺序 df["origin_idx"] = df.index # 转换日期格式,dayfirst=True适配日-月-年的日期字符串 df["start_date"] = pd.to_datetime(df["start_date"], dayfirst=True) df["end_date"] = pd.to_datetime(df["end_date"], dayfirst=True) # 按客户+开始时间排序,还原流转时间线 df = df.sort_values(by=["client_id", "start_date"], ascending=[True, True]) # 生成source、target字段 df["source"] = df["position"] df["target"] = df.groupby("client_id")["position"].shift(-1).fillna(4).astype(int) # 【可选步骤】恢复原始行顺序,不需要可跳过 df = df.sort_values(by="origin_idx").drop(columns=["origin_idx"]) # 【可选步骤】将日期转回原始字符串格式 df["start_date"] = df["start_date"].dt.strftime("%d-%m-%Y") df["end_date"] = df["end_date"].dt.strftime("%d-%m-%Y")
注意事项
- 如果数据中存在同一客户的时间段重叠、时间断层等异常,需要先做数据清洗再计算,否则会生成错误的流转关系
- 代码运行后可以用给出的client_id=1234的样例数据校验,输出结果和预期效果完全一致
内容的提问来源于stack exchange,提问作者Glarp
相关产品推荐
相关产品推荐

