如何在Pandas DataFrame中拆分m:n关系生成双向关联边?
生成交易关联人员的双向网络边
假设原始数据结构
先明确你的DataFrame结构,这里举两种常见情况:
情况1:关联人员存储为列表列
import pandas as pd df = pd.DataFrame({ '交易ID': ['T001', 'T002', 'T003'], '关联人员': [['张三', '李四'], ['王五', '赵六', '孙七'], ['张三', '王五']] })
情况2:关联人员分散在多列中
df = pd.DataFrame({ '交易ID': ['T001', 'T002'], '人员1': ['张三', '王五'], '人员2': ['李四', '赵六'], '人员3': [None, '孙七'] })
核心处理步骤
不管哪种情况,核心是为每笔交易内的所有人员生成两两双向边(即A→B和B→A都保留),具体代码如下:
步骤1:统一数据格式(针对情况2)
如果是多列存储人员,先合并为非空的列表列:
# 选取所有人员列,合并为无空值的列表 df['关联人员'] = df.filter(like='人员').apply(lambda x: x.dropna().tolist(), axis=1)
步骤2:生成双向边
from itertools import combinations # 1. 生成每笔交易内的人员两两无向边对(不重复组合) edge_pairs = df.groupby('交易ID')['关联人员'].apply( lambda people: list(combinations(people, 2)) ).explode().dropna() # 2. 拆分边对为起点、终点列 edges = pd.DataFrame(edge_pairs.tolist(), columns=['起点', '终点']) # 3. 生成双向边:复制并反转起点终点 reverse_edges = edges.rename(columns={'起点': '终点', '终点': '起点'}) bidirectional_edges = pd.concat([edges, reverse_edges], ignore_index=True)
最终结果示例
运行后得到的bidirectional_edges就是可用于网络可视化的双向边表,结构如下:
起点 终点 0 张三 李四 1 李四 张三 2 王五 赵六 3 赵六 王五 4 王五 孙七 5 孙七 王五 6 赵六 孙七 7 孙七 赵六 8 张三 王五 9 王五 张三
这个表可以直接导入NetworkX、Gephi等工具进行网络可视化。
内容的提问来源于stack exchange,提问作者Monatron
相关产品推荐
相关产品推荐

