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

使用NetworkX绘制数据时遭遇节点映射KeyError问题求助

问题描述

我首次尝试使用NetworkX,以下是我的示例代码:

import pandas as pd
import numpy as np

data = [{'Circuit_Number': 1,'Description':'Stadium', 'Duration':10, 'Device_County':'Westchester', 'Picklist':1000, 'Postlist':50000}, 
       {'Circuit_Number': 2, 'Description':'Stadium', 'Duration':12, 'Device_County':'Westchester', 'Picklist':3000, 'Postlist':40000},
       {'Circuit_Number': 2, 'Description':'Arena', 'Duration':11, 'Device_County':'Westchester', 'Picklist':7000, 'Postlist':50000}, 
       {'Circuit_Number': 3, 'Description':'Arena', 'Duration':8, 'Device_County':'Westchester', 'Picklist':3000, 'Postlist':40000},
       {'Circuit_Number': 3, 'Description':'Casino', 'Duration':6, 'Device_County':'Queens', 'Picklist':5000, 'Postlist':6000}, 
       {'Circuit_Number': 4, 'Description':'Casino', 'Duration':20, 'Device_County':'Queens', 'Picklist':5000, 'Postlist':4000},
       {'Circuit_Number': 4, 'Description':'Library', 'Duration':15, 'Device_County':'Brooklyn', 'Picklist':5000, 'Postlist':9000},
       {'Circuit_Number': 5, 'Description':'Library', 'Duration':7, 'Device_County':'Brooklyn', 'Picklist':6000, 'Postlist':10000}]
df = pd.DataFrame(data)
df

######################################################################################

import networkx as nx
import matplotlib.pyplot as plt

 
# Input data files check
from subprocess import check_output
 
import warnings
warnings.filterwarnings('ignore')
 
G = nx.Graph()

    
for index, row in df.iterrows():
    G.add_node(row['Circuit_Number'], group=row['Description'], nodesize=row['Duration'])
    
for index, row in df.iterrows():
    G.add_weighted_edges_from([(row['Device_County'], row['Picklist'], row['Postlist'])])
    
def draw_graph(G,size):
    nodes = G.nodes()
    color_map = {1000:'#f09494', 3000:'#eebcbc', 5000:'#72bbd0', 6000:'#91f0a1', 7000:'#629fff'}
    node_color = [color_map[d['Duration']] for n,d in G.nodes(data=True)]
    node_size = [d['Duration']*10 for n,d in G.nodes(data=True)]
    pos = nx.drawing.spring_layout(G,k=0.70,iterations=60)
    plt.figure(figsize=size)
    nx.draw_networkx(G,pos=pos,node_color=node_color,node_size=node_size,edge_color='#FFDEA2')
    plt.show()

draw_graph(G,size=(30,30))

运行后出现如下错误:

node_color = [color_map[d['Duration']] for n,d in G.nodes(data=True)]

KeyError: 'Duration'

我尝试将DataFrame中的数据导入NetworkX,生成类似下图的网络图,但无法成功绘制,请求帮助解决该问题。
参考网络图


问题分析与解决

核心问题

  1. 节点属性缺失:你只给Circuit_Number类型的节点添加了nodesize(对应Duration)属性,但添加边时自动创建的Device_County、Picklist节点没有Duration属性,遍历所有节点时触发KeyError。
  2. 颜色映射逻辑错误:color_map的键是Picklist的数值(1000/3000等),但你用Duration(6/7/10等)去匹配,两者完全不对应。
  3. 节点关系混乱:原代码没有明确节点类型,导致Circuit、地区、Picklist等不同类型节点混在一起,不符合参考图的多类型节点网络结构。

修正后的代码

import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt

# 原始数据
data = [{'Circuit_Number': 1,'Description':'Stadium', 'Duration':10, 'Device_County':'Westchester', 'Picklist':1000, 'Postlist':50000}, 
       {'Circuit_Number': 2, 'Description':'Stadium', 'Duration':12, 'Device_County':'Westchester', 'Picklist':3000, 'Postlist':40000},
       {'Circuit_Number': 2, 'Description':'Arena', 'Duration':11, 'Device_County':'Westchester', 'Picklist':7000, 'Postlist':50000}, 
       {'Circuit_Number': 3, 'Description':'Arena', 'Duration':8, 'Device_County':'Westchester', 'Picklist':3000, 'Postlist':40000},
       {'Circuit_Number': 3, 'Description':'Casino', 'Duration':6, 'Device_County':'Queens', 'Picklist':5000, 'Postlist':6000}, 
       {'Circuit_Number': 4, 'Description':'Casino', 'Duration':20, 'Device_County':'Queens', 'Picklist':5000, 'Postlist':4000},
       {'Circuit_Number': 4, 'Description':'Library', 'Duration':15, 'Device_County':'Brooklyn', 'Picklist':5000, 'Postlist':9000},
       {'Circuit_Number': 5, 'Description':'Library', 'Duration':7, 'Device_County':'Brooklyn', 'Picklist':6000, 'Postlist':10000}]
df = pd.DataFrame(data)

G = nx.Graph()

# 1. 添加Circuit节点,明确标注类型和属性
for _, row in df.iterrows():
    circuit_node = f"Circuit_{row['Circuit_Number']}"
    G.add_node(circuit_node, node_type="circuit", duration=row['Duration'], group=row['Description'])

# 2. 添加关联节点(设施、地区、Picklist)并建立连接
for _, row in df.iterrows():
    circuit_node = f"Circuit_{row['Circuit_Number']}"
    
    # 连接Circuit与设施(Description)
    desc_node = row['Description']
    G.add_node(desc_node, node_type="facility")
    G.add_edge(circuit_node, desc_node, weight=row['Postlist'])
    
    # 连接Circuit与地区(Device_County)
    county_node = row['Device_County']
    G.add_node(county_node, node_type="county")
    G.add_edge(circuit_node, county_node, weight=row['Postlist'])
    
    # 连接Circuit与Picklist
    picklist_node = row['Picklist']
    G.add_node(picklist_node, node_type="picklist")
    G.add_edge(circuit_node, picklist_node, weight=row['Postlist'])

def draw_graph(G, size):
    # 按节点类型分配颜色
    color_map = {
        "circuit": "#f09494",
        "facility": "#eebcbc",
        "county": "#72bbd0",
        "picklist": "#91f0a1"
    }
    
    node_color = []
    node_size = []
    for n, d in G.nodes(data=True):
        # Circuit节点大小由Duration决定,其他节点统一大小
        if d['node_type'] == "circuit":
            node_size.append(d['duration'] * 100)
        else:
            node_size.append(600)
        node_color.append(color_map[d['node_type']])
    
    pos = nx.spring_layout(G, k=0.70, iterations=60)
    plt.figure(figsize=size)
    
    # 绘制节点、边和标签
    nx.draw_networkx_nodes(G, pos, node_color=node_color, node_size=node_size)
    nx.draw_networkx_edges(G, pos, edge_color='#FFDEA2', width=[d['weight']/10000 for _,_,d in G.edges(data=True)])
    nx.draw_networkx_labels(G, pos, font_size=10)
    
    plt.show()

draw_graph(G, size=(30,30))

关键修正说明

  • 节点类型明确:给所有节点添加node_type属性,避免属性缺失报错,同时区分不同类型节点。
  • 逻辑关系清晰:建立Circuit节点与设施、地区、Picklist的连接,符合参考图的多节点类型网络结构。
  • 可视化优化:按节点类型分配颜色,Circuit节点大小关联Duration,边宽度关联Postlist,更贴合数据含义。
  • 避免重复节点:NetworkX自动忽略重复添加的节点,无需手动去重。

内容的提问来源于stack exchange,提问作者ASH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 10:26:04