Graph—具有自环的无向图#

概述#

class Graph(incoming_graph_data=None, **attr)[source]#

无向图的基类。

Graph 存储节点和边,并带有可选数据或属性。

Graph 包含无向边。允许自环,但不允许多条(并行)边。

节点可以是任意(可哈希)Python 对象,带有可选的键/值属性,除了不允许将 None 作为节点。

边表示节点之间的连接,带有可选的键/值属性。

参数
incoming_graph_data输入图(可选,默认为 None)

用于初始化图的数据。如果为 None(默认),则创建一个空图。数据可以是 to_networkx_graph() 函数支持的任何格式,当前包括边列表、字典的字典、列表的字典、NetworkX 图、二维 NumPy 数组、SciPy 稀疏矩阵或 PyGraphviz 图。

attr关键字参数,可选(默认=无属性)

以键=值对形式添加到图的属性。

示例

创建一个不包含节点和边的空图结构(“空图”)。

>>> G = nx.Graph()

G 可以通过几种方式增长。

节点

一次添加一个节点

>>> G.add_node(1)

从任何容器(列表、字典、集合,甚至文件中的行或来自另一个图的节点)添加节点。

>>> G.add_nodes_from([2, 3])
>>> G.add_nodes_from(range(100, 110))
>>> H = nx.path_graph(10)
>>> G.add_nodes_from(H)

除了字符串和整数,任何可哈希的 Python 对象(除了 None)都可以表示一个节点,例如自定义节点对象,甚至是另一个 Graph。

>>> G.add_node(H)

G 也可以通过添加边来增长。

添加一条边,

>>> G.add_edge(1, 2)

一个边列表,

>>> G.add_edges_from([(1, 2), (1, 3)])

或一个边集合,

>>> G.add_edges_from(H.edges)

如果某些边连接的节点尚不存在于图中,则会自动添加这些节点。添加已存在的节点或边不会出错。

属性

每个图、节点和边都可以将其键/值属性对保存在相关的属性字典中(键必须是可哈希的)。默认情况下,这些字典是空的,但可以使用 add_edge、add_node 或直接操作分别名为 graph、node 和 edge 的属性字典来添加或更改属性。

>>> G = nx.Graph(day="Friday")
>>> G.graph
{'day': 'Friday'}

使用 add_node()、add_nodes_from() 或 G.nodes 添加节点属性

>>> G.add_node(1, time="5pm")
>>> G.add_nodes_from([3], time="2pm")
>>> G.nodes[1]
{'time': '5pm'}
>>> G.nodes[1]["room"] = 714  # node must exist already to use G.nodes
>>> del G.nodes[1]["room"]  # remove attribute
>>> list(G.nodes(data=True))
[(1, {'time': '5pm'}), (3, {'time': '2pm'})]

使用 add_edge()、add_edges_from()、下标表示法或 G.edges 添加边属性。

>>> G.add_edge(1, 2, weight=4.7)
>>> G.add_edges_from([(3, 4), (4, 5)], color="red")
>>> G.add_edges_from([(1, 2, {"color": "blue"}), (2, 3, {"weight": 8})])
>>> G[1][2]["weight"] = 4.7
>>> G.edges[1, 2]["weight"] = 4

警告:我们通过使 G.edges 成为只读的类似字典的结构来保护图数据结构。但是,您可以在例如 G.edges[1, 2] 中为属性赋值。因此,使用两对括号来添加/更改数据属性:G.edges[1, 2]['weight'] = 4 (对于多重图:MG.edges[u, v, key][name] = value)。

快捷方式

许多常见的图功能允许使用 Python 语法来加快报告速度。

>>> 1 in G  # check if node in graph
True
>>> [n for n in G if n < 3]  # iterate through nodes
[1, 2]
>>> len(G)  # number of nodes in graph
5

通常遍历图所有边的最佳方式是通过邻居。邻居以邻接字典 G.adjG.adjacency() 的形式报告。

>>> for n, nbrsdict in G.adjacency():
...     for nbr, eattr in nbrsdict.items():
...         if "weight" in eattr:
...             # Do something useful with the edges
...             pass

但 edges() 方法通常更方便

>>> for u, v, weight in G.edges.data("weight"):
...     if weight is not None:
...         # Do something useful with the edges
...         pass

报告

简单的图信息可以通过对象属性和方法获取。报告通常提供视图而不是容器以减少内存使用。视图随着图的更新而更新,类似于字典视图。对象 nodesedgesadj 通过查找(例如 nodes[n]edges[u, v]adj[u][v])和迭代(例如 nodes.items()nodes.data('color')nodes.data('color', default='blue') 以及类似地对于 edges)提供对数据属性的访问。视图存在于 nodesedgesneighbors()/adjdegree

有关这些方法及其他杂项方法的详细信息,请参阅下文。

子类(高级)#

Graph 类使用字典的字典的字典数据结构。外部字典 (node_dict) 按节点键存储邻接信息。下一个字典 (adjlist_dict) 表示邻接信息并按邻居键存储边数据。内部字典 (edge_attr_dict) 表示边数据并按属性名键存储边属性值。

这三个字典中的每一个都可以在子类中被用户定义的类似字典的对象替换。通常,应保持类似字典的特性,但可以添加额外功能。要替换其中一个字典,可以通过更改保存该类似字典结构工厂的类(!)变量来创建新的图类。

node_dict_factory函数,(默认:dict)

用于创建包含节点属性(按节点 ID 键控)的字典的工厂函数。它不应需要参数并返回一个类似字典的对象

node_attr_dict_factory: 函数,(默认:dict)

用于创建节点属性字典(按属性名键控属性值)的工厂函数。它不应需要参数并返回一个类似字典的对象

adjlist_outer_dict_factory函数,(默认:dict)

用于创建数据结构中最外层字典(按节点键控邻接信息)的工厂函数。它不应需要参数并返回一个类似字典的对象。

adjlist_inner_dict_factory函数,(默认:dict)

用于创建邻接列表字典(按邻居键控边数据)的工厂函数。它不应需要参数并返回一个类似字典的对象

edge_attr_dict_factory函数,(默认:dict)

用于创建边属性字典(按属性名键控属性值)的工厂函数。它不应需要参数并返回一个类似字典的对象。

graph_attr_dict_factory函数,(默认:dict)

用于创建图属性字典(按属性名键控属性值)的工厂函数。它不应需要参数并返回一个类似字典的对象。

通常,如果您的扩展不影响数据结构,则所有方法都可以无问题地继承,除了:to_directed/to_undirected。默认情况下,这些方法创建 DiGraph/Graph 类,您可能希望它们创建您的 DiGraph/Graph 扩展。为了方便这一点,我们在您的子类中定义了两个可以设置的类变量。

to_directed_class可调用对象,(默认:DiGraph 或 MultiDiGraph)

to_directed 方法中用于创建新图结构的类。如果为 None,则使用 NetworkX 类(DiGraph 或 MultiDiGraph)。

to_undirected_class可调用对象,(默认:Graph 或 MultiGraph)

to_undirected 方法中用于创建新图结构的类。如果为 None,则使用 NetworkX 类(Graph 或 MultiGraph)。

子类化示例#

创建一个低内存图类,通过为所有边使用单个属性字典来有效地禁用边属性。这减少了内存使用,但您会丢失边属性。

>>> class ThinGraph(nx.Graph):
...     all_edge_dict = {"weight": 1}
...
...     def single_edge_dict(self):
...         return self.all_edge_dict
...
...     edge_attr_dict_factory = single_edge_dict
>>> G = ThinGraph()
>>> G.add_edge(2, 1)
>>> G[2][1]
{'weight': 1}
>>> G.add_edge(2, 2)
>>> G[2][1] is G[2][2]
True

方法#

添加和移除节点和边#

Graph.__init__([incoming_graph_data])

使用边、名称或图属性初始化图。

Graph.add_node(node_for_adding, **attr)

添加单个节点 node_for_adding 并更新节点属性。

Graph.add_nodes_from(nodes_for_adding, **attr)

添加多个节点。

Graph.remove_node(n)

移除节点 n。

Graph.remove_nodes_from(nodes)

移除多个节点。

Graph.add_edge(u_of_edge, v_of_edge, **attr)

在 u 和 v 之间添加一条边。

Graph.add_edges_from(ebunch_to_add, **attr)

添加 ebunch_to_add 中的所有边。

Graph.add_weighted_edges_from(ebunch_to_add)

添加 ebunch_to_add 中的加权边,并指定权重属性

Graph.remove_edge(u, v)

移除 u 和 v 之间的边。

Graph.remove_edges_from(ebunch)

移除 ebunch 中指定的所有边。

Graph.update([edges, nodes])

使用节点/边/图作为输入更新图。

Graph.clear()

从图中移除所有节点和边。

Graph.clear_edges()

从图中移除所有边,但不改变节点。

报告节点、边和邻居#

Graph.nodes

作为 G.nodes 或 G.nodes() 的图的 NodeView。

Graph.__iter__()

遍历节点。

Graph.has_node(n)

如果图包含节点 n,则返回 True。

Graph.__contains__(n)

如果 n 是一个节点,则返回 True,否则返回 False。

Graph.edges

作为 G.edges 或 G.edges() 的图的 EdgeView。

Graph.has_edge(u, v)

如果边 (u, v) 在图中,则返回 True。

Graph.get_edge_data(u, v[, default])

返回与边 (u, v) 关联的属性字典。

Graph.neighbors(n)

返回节点 n 所有邻居的迭代器。

Graph.adj

保存每个节点邻居的图邻接对象。

Graph.__getitem__(n)

返回节点 n 邻居的字典。

Graph.adjacency()

返回所有节点 (node, adjacency dict) 元组的迭代器。

Graph.nbunch_iter([nbunch])

返回 nbunch 中包含的且同时也在图中的节点的迭代器。

计数节点、边和邻居#

Graph.order()

返回图中的节点数。

Graph.number_of_nodes()

返回图中的节点数。

Graph.__len__()

返回图中的节点数。

Graph.degree

作为 G.degree 或 G.degree() 的图的 DegreeView。

Graph.size([weight])

返回边的数量或所有边权重的总和。

Graph.number_of_edges([u, v])

返回两个节点之间的边数。

创建副本和子图#

Graph.copy([as_view])

返回图的副本。

Graph.to_undirected([as_view])

返回图的无向副本。

Graph.to_directed([as_view])

返回图的有向表示。

Graph.subgraph(nodes)

返回在 nodes 上导出的子图的 SubGraph 视图。

Graph.edge_subgraph(edges)

返回由指定边导出的子图。