MultiGraph—包含自环和并行边的无向图#

概述#

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

一个可以存储多条边的无向图类。

多条边是指在两个节点之间的多条连线。每条边可以包含可选的数据或属性。

MultiGraph 存储无向边。允许自环。

节点可以是任意(可哈希的)Python 对象,具有可选的键/值属性。按照惯例,None 不用作节点。

边表示节点之间的连接,具有可选的键/值属性。在 MultiGraph 中,每条边都有一个键,用于区分源节点和目标节点相同的多条边。

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

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

multigraph_input布尔值或 None(默认为 None)

注意:仅当 incoming_graph_data 是字典时使用。如果为 True,则假定 incoming_graph_data 是一个字典的字典的字典的字典结构,键为节点到邻居到边键到多条边的边数据。如果不是这种情况,则会引发 NetworkXError。如果为 False,则使用 to_networkx_graph() 尝试确定字典的图数据结构,作为以节点到邻居到边数据为键的字典的字典的字典,或以节点到邻居为键的可迭代对象的字典。如果为 None,则尝试 True 的处理方式,如果失败,则尝试 False 的处理方式。

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

作为键值对添加到图的属性。

另请参阅

Graph
DiGraph
MultiDiGraph

示例

创建一个没有节点和边的空图结构(“空图”)。

>>> G = nx.MultiGraph()

图 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 也可以通过添加边来增长。

添加一条边,

>>> key = G.add_edge(1, 2)

一个边的列表,

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

或一个边的集合,

>>> keys = G.add_edges_from(H.edges)

如果某些边连接了图中尚不存在的节点,则会自动添加这些节点。如果边已存在,则会创建并存储一条额外的边,使用键来标识该边。默认情况下,键是最低的未使用整数。

>>> keys = G.add_edges_from([(4, 5, {"route": 28}), (4, 5, {"route": 37})])
>>> G[4]
AdjacencyView({3: {0: {}}, 5: {0: {}, 1: {'route': 28}, 2: {'route': 37}}})

属性

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

>>> G = nx.MultiGraph(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
>>> 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 添加边属性。

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

警告:我们通过使 G.edges[1, 2, 0] 成为只读的类似字典的结构来保护图的数据结构。但是,你可以在例如 G.edges[1, 2, 0] 中为属性赋值。因此,使用两组方括号来添加/更改数据属性:G.edges[1, 2, 0]['weight'] = 4

快捷方式

许多常见的图特性允许使用 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[1]  # adjacency dict-like view mapping neighbor -> edge key -> edge attributes
AdjacencyView({2: {0: {'weight': 4}, 1: {'color': 'blue'}}})

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

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

但 edges() 方法通常更方便

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

报告

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

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

子类(高级)#

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

字典的字典的字典的字典结构中的这四个字典中的每一个都可以替换为用户定义的类似字典的对象。通常,应保留类似字典的特性,但可以添加额外的特性。要替换其中一个字典,请通过更改保存该类似字典结构工厂的类(!)变量来创建新的图类。变量名包括 node_dict_factory、node_attr_dict_factory、adjlist_inner_dict_factory、adjlist_outer_dict_factory、edge_key_dict_factory、edge_attr_dict_factory 和 graph_attr_dict_factory。

node_dict_factory函数,(默认:dict)

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

node_attr_dict_factory: 函数,(默认:dict)

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

adjlist_outer_dict_factory函数,(默认:dict)

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

adjlist_inner_dict_factory函数,(默认:dict)

用于创建邻接列表字典的工厂函数,该字典按邻居键存储多边键字典。它不应需要参数,并应返回一个类似字典的对象。

edge_key_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

方法#

添加和移除节点及边#

MultiGraph.__init__([incoming_graph_data, ...])

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

MultiGraph.add_node(node_for_adding, **attr)

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

MultiGraph.add_nodes_from(nodes_for_adding, ...)

添加多个节点。

MultiGraph.remove_node(n)

移除节点 n。

MultiGraph.remove_nodes_from(nodes)

移除多个节点。

MultiGraph.add_edge(u_for_edge, v_for_edge)

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

MultiGraph.add_edges_from(ebunch_to_add, **attr)

添加 ebunch_to_add 中的所有边。

MultiGraph.add_weighted_edges_from(ebunch_to_add)

添加 ebunch_to_add 中指定权重的边

MultiGraph.new_edge_key(u, v)

返回节点 uv 之间未使用的边键。

MultiGraph.remove_edge(u, v[, key])

移除 u 和 v 之间的一条边。

MultiGraph.remove_edges_from(ebunch)

移除 ebunch 中指定的所有边。

MultiGraph.update([edges, nodes])

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

MultiGraph.clear()

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

MultiGraph.clear_edges()

移除图中的所有边,而不改变节点。

报告节点、边和邻居#

MultiGraph.nodes

图的 NodeView,即 G.nodes 或 G.nodes()。

MultiGraph.__iter__()

迭代遍历节点。

MultiGraph.has_node(n)

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

MultiGraph.__contains__(n)

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

MultiGraph.edges

返回边的迭代器。

MultiGraph.has_edge(u, v[, key])

如果图在节点 u 和 v 之间有一条边,则返回 True。

MultiGraph.get_edge_data(u, v[, key, default])

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

MultiGraph.neighbors(n)

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

MultiGraph.adj

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

MultiGraph.__getitem__(n)

返回节点 n 的邻居字典。

MultiGraph.adjacency()

返回所有节点的 (节点, 邻接字典) 元组的迭代器。

MultiGraph.nbunch_iter([nbunch])

返回 nbunch 中且也在图中的节点的迭代器。

统计节点、边和邻居#

MultiGraph.order()

返回图中的节点数量。

MultiGraph.number_of_nodes()

返回图中的节点数量。

MultiGraph.__len__()

返回图中的节点数量。

MultiGraph.degree

图的 DegreeView,即 G.degree 或 G.degree()。

MultiGraph.size([weight])

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

MultiGraph.number_of_edges([u, v])

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

创建副本和子图#

MultiGraph.copy([as_view])

返回图的一个副本。

MultiGraph.to_undirected([as_view])

返回图的一个无向副本。

MultiGraph.to_directed([as_view])

返回图的一个有向表示。

MultiGraph.subgraph(nodes)

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

MultiGraph.edge_subgraph(edges)

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