ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

NetworkX 图论函数接口全解:从 Graph 到 Nodes、Edges、Attributes 与 freeze 的官方 Functions API 实战指南

NetworkX 图论函数接口全解:从 Graph 到 Nodes、Edges、Attributes 与 freeze 的官方 Functions API 实战指南 NetworkX 图论函数接口全解从 Graph 到 Nodes、Edges、Attributes 与 freeze 的官方 Functions API 实战指南【免费下载链接】networkxNetwork Analysis in Python项目地址: https://gitcode.com/gh_mirrors/ne/networkx导读本文围绕 NetworkX 官方参考文档 doc/reference/functions.rst 所定义的Functions函数接口模块展开系统讲解networkx.classes.function中面向图对象的一整套函数式 API——包括 Graph 级操作密度、子图、方向转换、Nodes/Edges 视图查询、Self loops自环处理、节点与边属性读写、路径校验与权重求和以及图的冻结freeze机制。读者学完后将能用函数式调用替代冗长的对象方法调用理解每个函数的参数语义与返回值形态并掌握其底层实现原理本文所有代码示例均可直接复制运行全部行为可由 networkx/classes/function.py 及其测试 networkx/classes/tests/test_function.py 验证。一、函数式接口把图方法包装成独立函数NetworkX 的核心数据结构是Graph、DiGraph、MultiGraph、MultiDiGraph四个类见 networkx/classes/init.py它们各自带有大量方法。而networkx.classes.function模块约 1600 行见 networkx/classes/function.py提供的是与图类型解耦的独立函数每个函数接收图对象G作为第一个参数内部大多直接委托给对应的方法或视图属性。例如nodes(G)的源码只是def nodes(G): Returns a NodeView over the graph nodes. This function wraps the :func:G.nodes networkx.Graph.nodes property. return G.nodes()edges(G, nbunchNone)、degree(G, nbunchNone, weightNone)、neighbors(G, n)等也遵循同样的薄包装模式。这种设计带来两个好处一是算法代码可以统一以nx.xxx(G)的形式调用无需关心G究竟是Graph还是DiGraph二是为后端分发backends dispatch提供了统一入口如set_node_attributes、get_edge_attributes等函数标注了nx._dispatchable装饰器。从模块的__all__声明networkx/classes/function.py可以看出该模块除了文档列出的函数外还额外导出了remove_node_attributes、remove_edge_attributes、describe等工具。官方文档将全部函数按职责划分为Graph / Nodes / Edges / Self loops / Attributes / Paths / Freezing graph structure七组下文逐组展开。二、Graph 组图级别的结构查询与构造文档中 Graph 组包含 15 个函数覆盖图的整体度量、方向、空图判断、子图与结构追加。2.1 图的整体度量density、degree_histogram、is_emptydensity(G)返回图的密度。无向图公式为d 2m / (n(n-1))有向图为d m / (n(n-1))其中n为节点数、m为边数。源码networkx/classes/function.py在m 0 or n 1时直接返回 0否则计算后对无向图乘 2。密度为 0 表示无边图为 1 表示完全图多重图或含自环的图密度可以大于 1自环计入总边数。 G nx.path_graph(4) nx.density(G) 0.5degree_histogram(G)返回稠密度频分布列表下标即度值元素为具有该度的节点数缺失的度值补 0实现基于collections.Counter见 networkx/classes/function.py。注意列表长度可达number_of_edges量级。 G nx.star_graph(5) nx.degree_histogram(G) [0, 5, 0, 0, 0, 1] # 度0:0个, 度1:5个, ..., 度5:1个 dict(enumerate(nx.degree_histogram(G))) {0: 0, 1: 5, 2: 0, 3: 0, 4: 0, 5: 1}若只要稀疏表示可直接用Counter(d for _, d in G.degree)。is_empty(G)返回True当且仅当图中没有边可以有孤立节点。实现是not any(G._adj.values())时间复杂度 O(n)networkx/classes/function.py。零节点的空图被称为 null graph。2.2 方向is_directed、to_directed、to_undirectedis_directed(G)等价于G.is_directed()。to_directed(graph)/to_undirected(graph)返回图的**视图view**而非副本——内部固定调用graph.to_directed(as_viewTrue)/graph.to_undirected(as_viewTrue)networkx/classes/function.py。这与G.to_directed()默认as_viewFalse的行为不同用函数式 API 得到的视图与原图共享数据对原图的修改会反映到视图中。 G nx.Graph([(0, 1), (1, 2)]) D nx.to_directed(G) D.is_directed() True nx.to_undirected(D).is_directed() Falsecreate_empty_copy(G, with_dataTrue)返回一个同类型G.__class__()但所有边被移除的副本with_dataTrue默认时节点数据与图级G.graph数据会被保留networkx/classes/function.py。2.3 结构追加add_star、add_path、add_cycle三个函数都接受容器 关键字属性的方式向现有图G_to_add_to批量添加结构**attr会作为每条新边的属性如weight2add_star(G, nodes_for_star, **attr)nodes_for_star的第一个节点作为中心与其余所有节点相连。add_path(G, nodes_for_path, **attr)按顺序把节点连成一条路径每对相邻节点一条边。add_cycle(G, nodes_for_cycle, **attr)在路径基础上首尾相连形成环。三者底层都用pairwise迭代相邻节点add_cycle使用cyclicTrue空容器时静默返回见 networkx/classes/function.py。注意中心/首节点的选择是确定性的star 的中心是容器第一个元素因此add_star(G, [0,1,2,3])产生边(0,1),(0,2),(0,3)测试 networkx/classes/tests/test_function.py 对空列表、单元素、迭代器等多种边界情况都有覆盖。2.4 子图视图subgraph、induced_subgraph、restricted_view、edge_subgraph这是 Graph 组中最核心的一族函数。它们返回的都是只读视图SubGraph View不复制数据对原图G的修改会实时反映到视图中如需可变的独立副本用subgraph.copy()或Graph(subgraph)。subgraph(G, nbunch)等价于G.subgraph(nbunch)返回由nbunch中节点诱导的子图视图不在图中的节点被静默忽略networkx/classes/function.py。induced_subgraph(G, nbunch)返回节点诱导子图视图——节点集为nbunch边为两端都落在nbunch中的原图边。实现上通过nx.filters.show_nodes构造节点过滤器后调用nx.subgraph_viewnetworkx/classes/function.py。 G nx.path_graph(4) H nx.induced_subgraph(G, [0, 1, 3]) list(H.edges) [(0, 1)] # 边 (1,2)/(2,3) 因端点不在节点集内被过滤edge_subgraph(G, edges)返回边诱导子图视图——包含edges中的边及所有关联端点。不存在的边被忽略。多重图必须用三元组(u, v, key)指定边并可用边属性做条件过滤networkx/classes/function.py G nx.path_graph(5) H nx.edge_subgraph(G, [(0, 1), (3, 4)]) list(H.nodes) [0, 1, 3, 4]restricted_view(G, nodes, edges)与显示相反它隐藏指定的节点和边被隐藏的节点连带过滤其所有关联边networkx/classes/function.py G nx.path_graph(5) H nx.restricted_view(G, [0], [(1, 2), (3, 4)]) list(H.nodes) [1, 2, 3, 4] list(H.edges) [(2, 3)]这族函数依赖 networkx/classes/filters.py 中的过滤器工厂show_nodes、hide_edges、show_multiedges等最终统一交给 networkx/classes/graphviews.py 的subgraph_view构建视图。性能提示源码文档明确指出递归地子图的子图形成的视图链在约 15 层后会明显变慢建议始终基于原图构造视图G.subgraph在G本身是子图时会自动短路回原图而函数版本允许你自行选择是否叠链。三、Nodes 组节点集合、度数统计与邻居查询nodes(G)返回NodeView等价于G.nodesnetworkx/classes/reportviews.py 定义了该视图类型支持len()、成员判断与迭代。number_of_nodes(G)节点总数等价于len(G)。neighbors(G, n)返回节点n的邻居迭代器。对无向图是全部邻接节点对DiGraph只返回后继successors。all_neighbors(graph, node)在neighbors基础上对有向图额外合并前驱predecessors。前驱与后继可能产生重复元素如双向边或自环 DG nx.DiGraph([(0, 1), (1, 2), (2, 1)]) list(nx.all_neighbors(DG, 1)) [0, 2, 2]non_neighbors(graph, node)返回图中不是该节点邻居的所有节点集合含自身排除实现为集合差运算graph._adj.keys() - graph._adj[node].keys() - {node}networkx/classes/function.py。common_neighbors(G, u, v)返回两个节点共同的邻居集合仅适用于无向图装饰器not_implemented_for(directed)会拒绝有向图且u或v不在图中时抛出NetworkXErrornetworkx/classes/function.py G nx.complete_graph(5) sorted(nx.common_neighbors(G, 0, 1)) [2, 3, 4]四、Edges 组边集合、边数与补边枚举edges(G, nbunchNone)返回EdgeView对DiGraph即出边视图out_edges。nbunch给定时只返回与这些节点关联的边。在报告视图类EdgeView/OutEdgeViewnetworkx/classes/reportviews.py基础上视图还支持dataTrue携带属性字典。number_of_edges(G)边总数。non_edges(graph)生成器逐个产出图中不存在的边。有向图按(u, v)逐个节点对检查无向图用弹出节点 集合差避免重复networkx/classes/function.py。对多重图MultiGraph无效——多重图同一节点对可有多条平行边non_edges的语义不再成立。五、Self loops 组自环边的三个视角自环self-loop指两端为同一节点的边如(1, 1)。文档提供三个互补函数selfloop_edges(G, dataFalse, keysFalse, defaultNone)迭代器遍历所有自环边。data控制返回形态False返回二元组(u, v)True返回三元组(u, v, datadict)传入字符串属性名则返回(u, v, datavalue)缺失属性用default填充。keysTrue时对多重图额外带上边键knetworkx/classes/function.py G nx.MultiGraph() G.add_edge(1, 1); G.add_edge(1, 2) list(nx.selfloop_edges(G)) [(1, 1)] list(nx.selfloop_edges(G, keysTrue, dataTrue)) [(1, 1, 0, {})]number_of_selfloops(G)自环边数量实现为sum(1 for _ in nx.selfloop_edges(G))。nodes_with_selfloops(G)迭代器产出至少拥有一条自环的节点对多重图每节点只出现一次 G nx.Graph() G.add_edge(1, 1); G.add_edge(1, 2) list(nx.nodes_with_selfloops(G)) [1]自环会同时影响图的密度计算见 2.1 节的说明这是分析含自环网络时需要留意的细节。六、Attributes 组节点与边的属性读写这一组是实际工程中使用最频繁的函数文档单独强调了一个历史兼容性警告v1.x 与 v2.x 之间values与name两个参数的顺序互换过写新代码请严格按当前签名调用。6.1 设置属性set_node_attributes / set_edge_attributesset_node_attributes(G, values, nameNone)的参数语义有三种形态networkx/classes/function.py标量 name给所有节点设置同一属性值。字典 name{node: value}按节点赋值不在图中的节点静默忽略。字典的字典不传 name{node: {attr: value, ...}}整体更新各节点属性。 G nx.path_graph(3) bb nx.betweenness_centrality(G) nx.set_node_attributes(G, bb, betweenness) G.nodes[1][betweenness] 1.0可变对象陷阱如果values传的是列表等可变对象所有节点会共享同一个引用对列表的后续修改会传染到所有节点源码文档明确给出了此例。同理set_edge_attributes(G, values, nameNone)支持标量、{(u, v): value}、{(u, v): {attr: value}}三种形态多重图的字典键必须是三元组(u, v, key)networkx/classes/function.py MG nx.MultiGraph() MG.add_edges_from([(0, 1), (0, 1)]) # 返回边键列表 [0, 1] nx.set_edge_attributes(MG, {(0, 1, 0): {cost: 21}, (0, 1, 1): {cost: 7}}) MG[0][1][0][cost] 21两个 setter 都标注了nx._dispatchable(..., mutates_inputTrue)并会在修改后调用nx._clear_cache(G)使缓存失效。6.2 读取属性get_node_attributes / get_edge_attributesget_node_attributes(G, name, defaultNone)返回{node: 属性值}字典。default给定时缺失属性的节点以默认值入字典defaultNone默认时缺失属性的节点不出现在结果中networkx/classes/function.py。get_edge_attributes(G, name, defaultNone)同样语义但返回字典的键普通有向图为二元组(u, v)多重图为三元组(u, v, key)networkx/classes/function.py。 G nx.Graph() nx.add_path(G, [1, 2, 3], colorred) nx.get_edge_attributes(G, color) {(1, 2): red, (2, 3): red}6.3 权重探测is_weighted / is_negatively_weightedis_weighted(G, edgeNone, weightweight)默认检查图中每条边是否都带有weight属性全带返回True空图返回False规避all([]) True的陷阱。指定edge时只检查该边边不存在则抛NetworkXErrornetworkx/classes/function.py。is_negatively_weighted(G, edgeNone, weightweight)检查是否存在至少一条权重为负的边用any(...)实现networkx/classes/function.py。在选最短路径算法前用它预检负权边可以避免误用 Dijkstra。 G nx.path_graph(4) nx.is_weighted(G) False G nx.DiGraph(); G.add_edge(1, 2, weight1) nx.is_weighted(G) True七、Paths 组路径合法性与路径权重is_path(G, path)判断节点列表path是否构成一条有效路径——要求每个节点都存在且任意相邻节点对在图中相邻connected via one or more edges因此多重图同样适用。实现利用pairwise逐一检查邻接关系并捕获KeyError/TypeError返回Falsenetworkx/classes/function.py。path_weight(G, path, weight)返回沿path按指定边属性weight累加的总代价。先校验路径合法性不合法抛nx.NetworkXNoPath对多重图取同一节点对多条平行边中的最小权重参与累加min(v[weight] for v in G._adj[node][nbr].values())普通图直接读取该边权重networkx/classes/function.py。 G nx.path_graph(4) G[0][1][weight] 2; G[1][2][weight] 3; G[2][3][weight] 4 nx.path_weight(G, [0, 1, 2, 3], weight) 9八、Freezing graph structure图的冻结机制文档最后一组是freeze与is_frozen用于防止图的结构被意外修改——这在把图对象作为函数参数传递、防止下游代码误改数据时非常有用。freeze(G)将G的所有结构修改方法add_node、add_nodes_from、remove_node、add_edge、add_edges_from、add_weighted_edges_from、remove_edge、remove_edges_from、clear、clear_edges等替换为抛错函数frozen并置G.frozen True最后返回Gnetworkx/classes/function.py G nx.path_graph(4) G nx.freeze(G) try: ... G.add_edge(4, 5) ... except nx.NetworkXError as err: ... print(str(err)) Frozen graph cant be modifiedis_frozen(G)通过探测G.frozen属性判断是否冻结属性不存在如自定义图类时返回False。关键限制冻结只拦截结构修改节点与边的属性数据仍可修改G.nodes[0][x] 1合法。若需解冻必须通过构造新对象复制源码文档明确给出的标准做法 unfrozen_graph nx.Graph(frozen_graph) nx.is_frozen(unfrozen_graph) False九、源码结构、测试覆盖与进一步探索实现主体全部函数集中在 networkx/classes/function.py__all__见该文件 第 9-50 行并通过 networkx/classes/init.py 的from .function import *暴露为nx.xxx。配套视图类节点、边、度三种视图定义于 networkx/classes/reportviews.pyNodeView见 第 226 行、DegreeView见 第 586 行、EdgeView见 第 1297 行子图视图机制见 networkx/classes/graphviews.py 的subgraph_view。测试验证完整测试套件位于 networkx/classes/tests/test_function.py覆盖空图边界test_degree_histogram_empty、与对象方法的一致性断言如test_edges、test_degree、add_star/add_path/add_cycle的多种输入形态空列表、单元素、生成器以及describe信息字典等。运行测试pytest networkx/classes/tests/test_function.pydescribe(G, describe_hookNone)模块还附带一个未列入七组文档的实用函数一行打印图的概览节点数、边数、有向/多重标志、树/二分图判定、平均度、连通分量数、密度并可通过describe_hook注入自定义统计项networkx/classes/function.py是快速探查陌生图数据的便捷入口。结语networkx.classes.function是 NetworkX 中最贴近日常使用的函数层它把图对象的方法、视图与属性操作统一成nx.xxx(G, ...)的函数式调用七组函数分别覆盖图度量与构造、节点/边/自环查询、属性读写、路径计算与冻结保护。本文给出的全部示例都来自官方文档 docstring 与仓库测试的交叉验证可直接在本地 NetworkX 环境中运行复现。建议读者结合 doc/reference/functions.rst 的 API 索引按需深入阅读 networkx/classes/function.py 中每个函数的完整 docstring以获得最精确的参数行为说明。【免费下载链接】networkxNetwork Analysis in Python项目地址: https://gitcode.com/gh_mirrors/ne/networkx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表