将特定结构的Pandas DataFrame转换为加权邻接矩阵的技术需求
将Pandas DataFrame转换为基于共享ID的组加权邻接矩阵
针对你给出的需求——把包含id和group的DataFrame转换为以group为节点、以共享ID的组对计数之和为权重的无向加权图邻接矩阵,我整理了一套可复用的实现方案:
步骤1:导入依赖并构造示例数据
首先我们需要导入必要的库,并还原你提供的示例DataFrame:
import pandas as pd from itertools import combinations # 构造你给出的示例数据 df = pd.DataFrame({ 'id': ['abc', 'abc', 'abc', 'abc', 'def', 'def', 'ghi', 'ghi'], 'group': ['A', 'B', 'B', 'C', 'A', 'B', 'B', 'C'] })
步骤2:生成每个ID对应的组对组合
我们需要按id分组,对每个ID下的group列表生成无序且排序的两两组合(排序是为了避免(A,B)和(B,A)被当成不同组合重复统计):
# 对每个ID的group列生成排序后的2元组合,再展开为单行记录 group_combos = df.groupby('id')['group'].apply( lambda groups: list(combinations(sorted(groups), 2)) ).explode()
这一步处理后,group_combos会包含所有符合要求的组对,比如abc对应的(A,B)、(A,B)、(A,C)、(B,C)、(B,C),def对应的(A,B),ghi对应的(B,C)。
步骤3:统计组对的总权重
接下来统计每个组对出现的总次数,这就是我们需要的权重:
# 统计每个组对的计数,并重命名列 weight_stats = group_combos.value_counts().reset_index(name='weight') weight_stats.columns = ['group1', 'group2', 'weight']
此时weight_stats会显示:
| group1 | group2 | weight |
|---|---|---|
| A | B | 3 |
| B | C | 3 |
| A | C | 1 |
完全匹配你给出的示例计算结果!
步骤4:转换为对称邻接矩阵
最后我们把统计结果转换为标准的对称邻接矩阵(无向图的邻接矩阵是对称的):
# 先构造基础的邻接矩阵 adj_matrix = weight_stats.pivot(index='group1', columns='group2', values='weight').fillna(0) # 补充矩阵的对称部分,并确保所有组都被包含 all_groups = adj_matrix.columns.union(adj_matrix.index) adj_matrix = adj_matrix.reindex(index=all_groups, columns=all_groups, fill_value=0) # 填充对称位置的权重 for i in range(len(all_groups)): for j in range(i): adj_matrix.iloc[i, j] = adj_matrix.iloc[j, i]
最终生成的邻接矩阵如下:
group2 A B C group1 A 0.0 3.0 1.0 B 3.0 0.0 3.0 C 1.0 3.0 0.0
这个矩阵清晰展示了每个组对之间的加权连接:A-B权重3,A-C权重1,B-C权重3,完全符合你的预期。
内容的提问来源于stack exchange,提问作者BenP
相关产品推荐
相关产品推荐

