如何用带行列标题的CSV文件在NetworkX中绘制邻接矩阵
基于带标题的邻接矩阵CSV在NetworkX中创建图
你的CSV数据结构
| ANXIETY | HEADACHE | INSOMNIA | NAUSEA | |
|---|---|---|---|---|
| HEADACHE | 20 | 14 | 2 | |
| INSOMNIA | 11 | |||
| NAUSEA | 3 | 7 | 6 | 3 |
| ANXIETY | 11 | 5 |
问题分析
你用pd.read_csv读取文件时已经正确将第一列设为索引,此时DataFrame的行索引和列名就是图的节点名称,不需要额外提取。之前用df[1:,1:]报错是因为pandas的[]是标签切片,你的行标签是症状名称而非数字索引;用np.genfromtxt会丢失行列标签,无法直接对应节点。
解决方案
方法1:直接用NetworkX内置函数(推荐)
- 先处理空值:邻接矩阵中空值代表权重为0,需要先填充
import pandas as pd import networkx as nx import matplotlib.pyplot as plt # 读取文件 df = pd.read_csv('D:\\DistanceMatix.csv', sep=',', header=0, index_col=[0]) # 空值填充为0 df = df.fillna(0) # 从DataFrame创建图,自动用索引和列名作为节点,矩阵值作为边权重 G = nx.from_pandas_adjacency(df)
- 验证节点与边:
print("节点列表:", list(G.nodes())) print("边及权重:", list(G.edges(data=True)))
- 可视化图:
pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1500) edge_labels = nx.get_edge_attributes(G, 'weight') nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels) plt.show()
方法2:手动遍历添加节点和边
如果需要更灵活的控制(比如只保留权重>0的边),可以手动遍历DataFrame:
import pandas as pd import networkx as nx import matplotlib.pyplot as plt df = pd.read_csv('D:\\DistanceMatix.csv', sep=',', header=0, index_col=[0]) df = df.fillna(0) G = nx.Graph() # 添加所有节点 G.add_nodes_from(df.index.tolist()) # 遍历矩阵添加边 for source in df.index: for target in df.columns: weight = df.loc[source, target] if weight > 0: G.add_edge(source, target, weight=weight) # 后续验证和可视化同方法1
补充说明
如果你确实需要按位置切片提取子矩阵,应该用pandas的.iloc方法(位置索引),比如adjacency = df.iloc[1:,1:],但对于你的需求来说完全没必要,因为整个DataFrame就是完整的邻接矩阵。
内容的提问来源于stack exchange,提问作者Anand Rapaka
相关产品推荐
相关产品推荐

