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

NetworkX节点多属性分配报KeyError及多属性网络构建实现

报错核心原因

你遇到的KeyError: 87.5完全来自之前的节点收集逻辑错误:

  • 写的collist = df.drop('Weight', axis=1).melt('Label').dropna()执行后,melt生成的value列会把Attribute列的数值(比如第一行的87.5)也当成待计算度数的节点。这些数值从来没有作为Source/Target出现在边表里,图中不存在对应节点,查询度数时自然触发报错。
  • 之前绑定节点属性的逻辑没有对齐映射关系:没有区分“Source节点带Attribute、Label属性,Target节点不带任何专属属性”的规则,直接硬套属性映射,后续计算时很容易出现属性错位。
完整可运行的修正实现

1. 图构建与属性绑定

因为Attribute、Label是仅属于Source列节点的属性,不需要对所有节点通用,先提取唯一的属性映射表,避免重复边干扰属性对齐:

import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# 读取你的边表数据(替换成你自己的df加载逻辑即可)
df = pd.DataFrame({
    'Attribute': [87.5, 12.5, 12.5, 43.5],
    'Source': ['Heisenberg', 'Beckham', 'Beckham', 'water'],
    'Target': ['Pauli', 'Messi', 'Maradona', 'melon'],
    'Weight': [66.3, 38.1, 12, 33.6],
    'Label': [1, 0, 0, 1]
})

# 提取Source节点的专属属性,按Source去重(同一个Source出现在多行时取一次属性值即可)
source_attr_map = df[['Source', 'Attribute', 'Label']].drop_duplicates(subset=['Source'])
attr_dict = source_attr_map.set_index('Source')['Attribute'].to_dict()
label_dict = source_attr_map.set_index('Source')['Label'].to_dict()

# 建图,边属性绑定Weight
G = nx.from_pandas_edgelist(df, source='Source', target='Target', edge_attr='Weight')

# 给匹配到的Source节点绑定Attribute、Label属性,无匹配的Target节点自动跳过
nx.set_node_attributes(G, attr_dict, 'Attribute')
nx.set_node_attributes(G, label_dict, 'Label')

2. 节点大小、属性值计算

这里严格只从Source、Target两列收集所有真实存在的节点,彻底避免之前把Attribute数值当成节点的错误:

# 收集图里所有真实节点(仅来自Source和Target列)
all_nodes = pd.concat([df['Source'], df['Target']]).unique()

# 按节点列表计算对应大小(与度数成正比)
node_sizes = [100 * G.degree[node] for node in all_nodes]

# 生成每个节点对应的颜色值:Source节点用自身Label值,Target节点用默认中性值
node_colors = [G.nodes[node].get('Label', 0.5) for node in all_nodes]

3. 按参考逻辑更新Attribute值

完全匹配邻域平均的参考实现逻辑,同时跳过没有Attribute初始值的Target节点,不会出现属性计算错位:

updated_attrs = {}
for node in G.nodes:
    # 没有初始Attribute的节点(即Target节点),保持原状态
    if 'Attribute' not in G.nodes[node]:
        updated_attrs[node] = None
        continue
    # 收集所有带Attribute属性的邻居值,过滤不带属性的Target节点
    neighbor_attrs = [
        G.nodes[neighbor]['Attribute']
        for neighbor in G.neighbors(node)
        if 'Attribute' in G.nodes[neighbor]
    ]
    # 计算邻域平均
    if neighbor_attrs:
        new_val = (sum(neighbor_attrs) + G.nodes[node]['Attribute']) / (len(neighbor_attrs) + 1)
    else:
        new_val = G.nodes[node]['Attribute']
    updated_attrs[node] = new_val

# 统一把更新后的值写回节点
for node, new_val in updated_attrs.items():
    if new_val is not None:
        G.nodes[node]['Attribute'] = new_val

4. 绘图匹配规则

  • 边粗细与Weight值正相关
  • 节点颜色按规则映射:Label=1对应黄色,Label=0对应蓝色
# 固定布局种子,保证每次出图位置一致
pos = nx.spring_layout(G, seed=42)
# 缩放边权重,避免边过粗
edge_widths = [G.edges[edge]['Weight'] / 20 for edge in G.edges]
# 定义颜色映射:0=蓝色,1=黄色
color_map = ListedColormap(['#1a75bb', '#ffdd22'])

nx.draw_networkx_labels(G, pos, font_size=10)
nx.draw_networkx_nodes(
    G, pos,
    nodelist=all_nodes,
    node_size=node_sizes,
    node_color=node_colors,
    cmap=color_map,
    vmin=0, vmax=1
)
nx.draw_networkx_edges(G, pos, width=edge_widths)
plt.axis('off')
plt.show()
效果校验

运行后不会再出现KeyError报错:

  • 所有节点的大小与自身度数成正比
  • Source节点的颜色完全匹配Label规则(1黄0蓝),Target节点为默认中间色
  • Attribute属性仅绑定在Source节点上,更新逻辑与参考实现完全一致
  • 边的粗细与Weight值直接对应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 02:15:03