基于Pandas DataFrame构建NetworkX图:NaN边处理与节点大小问题
解决Pandas DataFrame构建导演网络图的NaN与节点绘制问题
核心处理思路
- 过滤无效边:直接丢弃
Score_pair为NaN的行,这类数据无法生成有效连接 - 确保节点Score唯一:同一个导演可能在DataFrame中重复出现,需提取唯一的Score值用于设置节点大小
- 匹配节点与属性长度:保证图中所有节点都有对应的Score值,避免绘制时出现长度不匹配的ValueError
完整可复现代码
import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # 模拟用户数据集结构 data = { 'directors': ['诺兰', '卡梅隆', '斯皮尔伯格', '诺兰', '卡梅隆'], 'pair_directors': ['卡梅隆', '诺兰', '诺兰', '斯皮尔伯格', np.nan], 'Score': [9.2, 8.8, 8.5, 9.2, 8.8], 'Score_pair': [0.7, 0.7, 0.5, 0.5, np.nan] } df = pd.DataFrame(data) # 1. 过滤无有效边的行 edge_df = df.dropna(subset=['Score_pair']) # 2. 构建网络图 G = nx.from_pandas_edgelist( edge_df, source='directors', target='pair_directors', edge_attr='Score_pair' ) # 3. 处理节点大小:提取唯一Score并缩放 node_score_map = df[['directors', 'Score']].drop_duplicates().set_index('directors')['Score'] # 对齐图中所有节点,避免孤立节点无Score导致错误 node_score_map = node_score_map.reindex(G.nodes(), fill_value=0) node_sizes = node_score_map * 1000 # 缩放系数可按需调整 # 4. 处理边的粗细:提取Score_pair并缩放 edge_widths = [G[u][v]['Score_pair'] * 5 for u, v in G.edges()] # 5. 绘制网络图 plt.figure(figsize=(10, 8)) pos = nx.spring_layout(G, seed=42) # 固定布局方便复现 nx.draw_networkx_nodes(G, pos=pos, node_size=node_sizes, node_color='skyblue', alpha=0.8) nx.draw_networkx_edges(G, pos=pos, width=edge_widths, edge_color='gray', alpha=0.6) nx.draw_networkx_labels(G, pos=pos, font_size=12, font_weight='bold') # 可选:绘制边的Score_pair标签 nx.draw_networkx_edge_labels(G, pos=pos, edge_labels={(u, v): round(G[u][v]['Score_pair'], 1) for u, v in G.edges()}) plt.axis('off') plt.tight_layout() plt.show()
错误原因解析
- NaN未过滤:
nx.from_pandas_edgelist无法处理源/目标节点为NaN的行,会生成无效节点或导致边构建失败 - 节点与大小不匹配:若未对导演的Score去重,或未对齐图中所有节点,会导致
node_sizes长度与节点数量不一致,触发ValueError - 缩放系数缺失:直接用原始Score作为节点大小会导致节点过小无法看清,需乘以合适的缩放系数
内容的提问来源于stack exchange,提问作者OliviaJ
相关产品推荐
相关产品推荐

