教程
参考文献
0 简单介绍 图的类型
Graph类是无向图的基类,无向图能有自己的属性或参数,不包含重边,允许有回路,节点可以是任何hash的python对象,节点和边可以保存key/value属性对。该类的构造函数为Graph(data=None,**attr),其中data可以是边列表,或任意一个Networkx的图对象,默认为none;attr是关键字参数,例如key=value对形式的属性。
MultiGraph是可以有重边的无向图,其它和Graph类似。其构造函数MultiGraph(data=None, *attr)。
DiGraph是有向图的基类,有向图可以有数自己的属性或参数,不包含重边,允许有回路;节点可以是任何hash的python对象,边和节点可含key/value属性对。该类的构造函数DiGraph(data=None,**attr),其中data可以是边列表,或任意一个Networkx的图对象,默认为none;attr是关键字参数,例如key=value对形式的属性。
MultiDiGraph是可以有重边的有向图,其它和DiGraph类似。其构造函数MultiDiGraph(data=None, *attr)
有向图 这个 DiGraph 提供了附加的属性,DiGraph.out_edges , DiGraph.in_degree , DiGraph.predecessors() , DiGraph.successors() 等。为了使算法能够轻松地与两个类一起工作,有向版本的 neighbors() 等于 successors() 虽然 degree 报告 in_degree 和 out_degree 尽管有时会觉得不一致。
1 2 3 4 5 6 7 8 9 10 DG = nx.DiGraph() DG.add_weighted_edges_from([(1 , 2 , 0.5 ), (3 , 1 , 0.75 )]) DG.out_degree(1 , weight='weight' ) 0.5 DG.degree(1 , weight='weight' ) 1.25 list (DG.successors(1 ))[2 ] list (DG.neighbors(1 ))[2 ]
有向图和无向图的转换
1 2 Graph.to_undirected() H = nx.Graph(G)
多重图 多重图 NetworkX为允许任意节点对之间存在多个边的图形提供类。这个 MultiGraph 和 MultiDiGraph 类允许您两次添加相同的边缘,可能使用不同的边缘数据。这对某些应用程序来说可能很强大,但许多算法在此类图上没有很好的定义。如果结果定义明确,例如: MultiGraph.degree() 我们提供功能。否则,您应该以一种使测量定义良好的方式转换为标准图。
1 2 3 4 5 6 7 8 9 10 11 12 MG = nx.MultiGraph() MG.add_weighted_edges_from([(1 , 2 , 0.5 ), (1 , 2 , 0.75 ), (2 , 3 , 0.5 )]) dict (MG.degree(weight='weight' )){1 : 1.25 , 2 : 1.75 , 3 : 0.5 } GG = nx.Graph() for n, nbrs in MG.adjacency(): for nbr, edict in nbrs.items(): minvalue = min ([d['weight' ] for d in edict.values()]) GG.add_edge(n, nbr, weight = minvalue) nx.shortest_path(GG, 1 , 3 ) [1 , 2 , 3 ]
1 增加 创建图形 创建一个没有节点和边的空图形。
1 2 3 >>> import networkx as nxG = nx.Graph()
根据定义,a Graph 是一组节点(顶点)和已识别的节点对(称为边、链接等)的集合。在NetworkX中,节点可以是任何 hashable 对象,例如文本字符串、图像、XML对象、另一个图形、自定义节点对象等
添加节点 图 G 可以通过多种方式生长。NetworkX包括许多图形生成器功能和以多种格式读取和写入图形的工具。我们先来看看简单的操作。
1 G.add_nodes_from([2 , 3 ])
如果容器产生2个元组形式,还可以添加节点和节点属性 (node, node_attribute_dict) ::
1 2 3 4 G.add_nodes_from([ (4 , {"color" : "red" }), (5 , {"color" : "green" }), ])
1 2 H = nx.path_graph(10 ) G.add_nodes_from(H)
G 现在包含的节点 H 作为节点 G . 相反,您可以使用图表 H 作为一个节点 G .
添加边缘
1 2 3 G.add_edge(1, 2) e = (2, 3) G.add_edge(*e) # unpack edge tuple*
1 G.add_edges_from([(1, 2), (1, 3)])
1 2 3 4 5 6 7 >>> G.add_edges_from([(1, 2), (1, 3)]) G.add_node(1) # 已经存在1节点,不再重复添加 G.add_edge(1, 2) # 已经存在1,2边,不再重复添加 G.add_node("spam") # adds node "spam" G.add_nodes_from("spam") # adds 4 nodes: 's', 'p', 'a', 'm' G.add_edge(3, 'm')
在这个阶段,图表 G 由8个节点和3个边组成,如下所示:
1 2 3 4 5 >>> G.number_of_nodes() 8 G.number_of_edges() 3
2 删除 删除元素 可以用与添加类似的方式从图形中删除节点和边。
Graph.remove_node()
Graph.remove_nodes_from()
Graph.remove_edge()
Graph.remove_edges_from()
1 2 3 4 5 6 >>> G.remove_node(2) G.remove_nodes_from("spam") list(G.nodes) [1, 3, 'spam'] G.remove_edge(1, 3)
构造函数 图形对象不必以增量方式构建——指定图形结构的数据可以直接传递给各种图形类的构造函数。当通过实例化一个图形类来创建一个图结构时,可以用几种格式指定数据。
1 2 3 4 5 6 G.add_edge(1, 2) H = nx.DiGraph(G) # create a DiGraph using the connections from G list(H.edges()) [(1, 2), (2, 1)] edgelist = [(0, 1), (1, 2), (2, 3)] H = nx.Graph(edgelist)
3 查找 访问边缘和邻居
除了视图 Graph.edges 和 Graph.adj ,可以使用下标表示法访问边和邻居。
1 2 3 4 5 6 7 G = nx.Graph([(1 , 2 , {"color" : "yellow" })]) G[1 ] AtlasView({2 : {'color' : 'yellow' & G[1 ][2 ] {'color' : 'yellow' } G.edges[1 , 2 ] {'color' : 'yellow' }
如果边已经存在,可以使用下标表示法获取/设置边的属性。
1 2 3 4 5 G.add_edge(1 , 3 ) G[1 ][3 ]['color' ] = "blue" G.edges[1 , 2 ]['color' ] = "red" G.edges[1 , 2 ] {'color' : 'red' }
使用 G.adjacency() 或 G.adj.items() . 注意,对于无向图,邻接迭代可以看到每个边两次。
1 2 3 4 5 6 7 8 9 10 FG = nx.Graph() FG.add_weighted_edges_from([(1 , 2 , 0.125 ), (1 , 3 , 0.75 ), (2 , 4 , 1.2 ), (3 , 4 , 0.375 )]) for n, nbrs in FG.adj.items(): for nbr, eattr in nbrs.items(): wt = eattr['weight' ] if wt < 0.5 : print (f"({n} , {nbr} , {wt:.3 } )" ) (1 , 2 , 0.125 ) (2 , 1 , 0.125 ) (3 , 4 , 0.375 ) (4 , 3 , 0.375 )
1 2 3 4 5 for (u, v, wt) in FG.edges.data('weight' ): if wt < 0.5 : print (f"({u} , {v} , {wt:.3 } )" ) (1 , 2 , 0.125 ) (3 , 4 , 0.375 )
4 修改 向图形、节点和边添加属性
诸如权重、标签、颜色或任何您喜欢的python对象等属性都可以附加到图形、节点或边上。
每个图、节点和边都可以在关联的属性字典中保存键/值属性对(键必须是可哈希的)。默认情况下,这些属性为空,但可以使用 add_edge , add_node 或直接操作命名的属性字典 G.graph , G.nodes 和 G.edges 对于图 G .
图形属性 创建新图形时分配图形属性
1 2 3 G = nx.Graph(day="Friday") G.graph {'day': 'Friday'}
或者您可以稍后修改属性
1 2 3 G.graph['day'] = "Monday" G.graph {'day': 'Monday'}
节点属性 使用添加节点属性 add_node() , add_nodes_from() 或 G.nodes
1 2 3 4 5 6 7 G.add_node(1 , time='5pm' ) G.add_nodes_from([3 ], time='2pm' ) G.nodes[1 ] {'time' : '5pm' } G.nodes[1 ]['room' ] = 714 G.nodes.data() NodeDataView({1 : {'time' : '5pm' , 'room' : 714 }, 3 : {'time' : '2pm' &
请注意,将节点添加到 G.nodes 不将其添加到图表中,使用 G.add_node() 添加新节点。同样适用于边缘。
边缘属性 使用添加/更改边缘属性 add_edge() , add_edges_from() 或下标符号。
1 2 3 4 5 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[3 , 4 ]['weight' ] = 4.2
特殊属性 weight 应该是数字,因为它被需要加权边缘的算法使用。