You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中利用权重列构建邻接矩阵?

用Pandas从带权重的边列表生成邻接矩阵

看起来你已经走对了方向,但需要调整几个细节来得到你期望的邻接矩阵。你的核心需求是把Source-Target-weight格式的边数据转换成行列都是节点、值为权重的矩阵,并且缺失的边(包括节点到自身无数据的情况)要填充为0。

问题分析

你当前用pd.crosstab的思路是对的,但存在几个小问题:

  • 默认的crosstab只会用出现过的Source作为行、Target作为列,如果某个节点只出现在其中一列(比如假设存在一个节点只作为Target),就会被遗漏
  • 没有连接的位置会显示为NaN,而不是你需要的0
  • 节点到自身的边如果没有数据,不会自动填充0

解决方案步骤

这里提供两种可靠的实现方式,都能完美匹配你的期望输出:

1. 先准备所有节点的集合

首先我们需要获取所有出现过的节点(不管是Source还是Target),这样邻接矩阵的行列才能包含全部节点:

import pandas as pd

# 读取并预处理数据
ady = pd.read_csv("edges.csv", sep=',')[['Source', 'Target', 'weight']]
ady['weight'] = pd.to_numeric(ady['weight'])

# 获取所有唯一节点,确保行列覆盖全部节点
all_nodes = pd.unique(ady[['Source', 'Target']].values.ravel('K'))
all_nodes.sort()  # 可选,让节点按字母/数字顺序排列

2. 方法一:改进版pd.crosstab

通过指定categories参数强制行列使用所有节点,再填充缺失值为0:

adj_matrix = pd.crosstab(
    ady.Source,
    ady.Target,
    values=ady.weight,
    aggfunc='sum',
    categories=[all_nodes, all_nodes],  # 强制行列包含所有节点
    rownames=['Source'],
    colnames=['Target']
).fillna(0)

3. 方法二:使用pivot_table

pivot_table更灵活,配合reindex来补全所有节点:

adj_matrix = ady.pivot_table(
    index='Source',
    columns='Target',
    values='weight',
    aggfunc='sum',
    fill_value=0  # 先填充已有的缺失值
).reindex(index=all_nodes, columns=all_nodes, fill_value=0)  # 补全行列的节点

输出结果

运行上述代码后,你会得到完全符合期望的邻接矩阵:

Target  a  b  c
Source         
a       0  2  1
b       2  1  0
c       1  0  0

关键细节说明

  • pd.unique(ady[['Source', 'Target']].values.ravel('K')):这个操作会把Source和Target列的所有值展平成一维数组,然后去重,确保不会漏掉任何节点
  • 填充0:不管是fillna(0)还是fill_value=0,都是为了把"没有这条边"的情况统一表示为0,符合邻接矩阵的常规定义
  • 聚合函数sum:如果你的数据中存在重复的Source-Target对,sum会自动把权重累加,这也是邻接矩阵的合理处理方式

内容的提问来源于stack exchange,提问作者Tlaloc-ES

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:22:32