如何在NetworkX中收缩节点并自动聚合节点属性(平均高度、求和面积)
NetworkX 自动收缩节点并合并属性(height取平均、area求和)
你可以通过自定义属性合并逻辑+封装收缩流程的方式,让NetworkX自动完成节点收缩时的属性计算,无需手动处理。以下是具体实现方案:
核心思路
- 编写一个属性合并函数,批量计算要收缩节点的
height平均值和area总和; - 封装一个通用的节点收缩函数,完成节点收缩、重命名、属性更新的全流程;
- 调用该函数即可快速完成任意节点集合的收缩操作。
完整代码示例
import networkx as nx # 1. 构建原始图 nodes_list = [("A", {"height":10, "area":100}), ("B", {"height":12, "area":200}), ("C", {"height":8, "area":150}), ("D", {"height":9, "area":120})] G = nx.Graph() G.add_nodes_from(nodes_list) edges_list = [("A","B"), ("B","C"), ("C","D")] G.add_edges_from(edges_list) # 2. 定义属性合并函数:计算height平均值、area总和 def merge_node_attributes(node_list, graph): heights = [graph.nodes[node]["height"] for node in node_list] areas = [graph.nodes[node]["area"] for node in node_list] return { "height": sum(heights) / len(heights), "area": sum(areas) } # 3. 封装通用收缩函数 def contract_nodes_with_attr(graph, nodes_to_contract, new_node_name): # 复制原图,避免修改原始数据 contracted_graph = graph.copy() # 计算合并后的属性 merged_attr = merge_node_attributes(nodes_to_contract, contracted_graph) # 将所有待收缩节点合并到第一个节点 base_node = nodes_to_contract[0] for node in nodes_to_contract[1:]: contracted_graph = nx.contract_nodes(contracted_graph, base_node, node, self_loops=False) # 重命名合并后的节点 contracted_graph = nx.relabel_nodes(contracted_graph, {base_node: new_node_name}) # 更新节点属性 contracted_graph.nodes[new_node_name].update(merged_attr) return contracted_graph # 4. 示例:收缩A、B节点为AB G_contracted = contract_nodes_with_attr(G, ["A", "B"], "AB") # 查看收缩结果 print("收缩后的节点属性:") for node, attrs in G_contracted.nodes(data=True): print(f"{node}: {attrs}") # 绘制收缩后的图 nx.draw(G_contracted, with_labels=True, node_color="lightblue")
关键说明
- 属性计算准确性:如果收缩多个节点(≥3个),不要用两两合并的方式计算平均值(多次平均会和总平均产生偏差),上述方案一次性收集所有节点的属性值计算,结果更准确;
- 灵活性:
contract_nodes_with_attr函数支持任意数量的节点收缩,只需传入待收缩节点列表和新节点名称即可; - 数据安全性:操作前复制原图,避免修改原始图数据。
内容的提问来源于stack exchange,提问作者Bera
相关产品推荐
相关产品推荐

