1简介
工具包NetworkX 可用于创建、操作和研究复杂网络的结构、动态和功能。
2教程
2.1创建网络拓扑图
创建一个没有节点,没有边的网络拓扑图。
>>> import networkx as nx
>>> G = nx.Graph()
。。。
好吧,写到这里发现了一个比我写的好的。。。
基本操作教程的链接贴到这里:
https://www.jianshu.com/p/e543dc63454f
这里说一说与上述文章不同的地方以及需要特别注意的地方
关于添加网络节点时的两个函数
add_node和add_nodes_from
对于add_node加一个点来说,字符串是只添加了名字为整个字符串的节点。但是对于add_nodes_from加一组点来说,字符串表示了添加了每一个字符都代表的多个节点,exp:
g.add_node("spam") #添加了一个名为spam的节点
g.add_nodes_from("spam") #添加了4个节点,名为s,p,a,m
加一组从0开始的连续数字的节点:
H = nx.path_graph(10)
g.add_nodes_from(H) #将0~9加入了节点
参考文中指出“但请勿使用g.add_node(H)”。但是官方的说法是,使用g.add_node(H)以后,H就可以作为G的一个节点存在了,这种做法会使拓扑图更加的灵活和强大。因为它允许图的图、文件的图、函数的图等等。值得思考的是如何构造应用程序,使节点成为有用的实体。当然,您总是可以在G中使用唯一的标识符,并且如果您愿意,还可以使用一个单独的字典,通过标识符对节点信息进行键控。
2.2向图、节点、边添加属性
属性包括:权重、标签、颜色或者其他的Python对象都可以添加到图、节点和边上。
每个图、节点和边缘都可以在关联的属性字典中保存键/值属性对(键必须是可hashable的)。默认的这些属性都是空的,但是可以通过函数添加。
2.2.1图属性
向图中添加属性:
>>> G = nx.Graph(day="Friday")
>>> G.graph
{'day': 'Friday'}
然后使用下面代码修改属性:
>>> G.graph['day'] = "Monday"
>>> G.graph
{'day': 'Monday'}
2.2.2节点属性
使用 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
>>> G.nodes.data()
NodeDataView({1: {'time': '5pm', 'room': 714}, 3: {'time': '2pm'}})
注意使用 G.nodes并不会将它添加到图中,而是只添加到节点, 使用G.add_node() 来添加新节点到图中. 边界的操作类似.
2.2.3边界属性
添加和改变边界的属性方法如下:
>>> 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
注意,在算法中使用权重的时候需要将权重数值化。
2.3有向图
DiGraph类提供了特定于有向边的附加属性,例如DiGraph.out_edges()、DiGraph.in_degree()、DiGraph.neighbors()、DiGraph.successors()等。为了让算法能够轻松地处理这两个类,neighbors()的定向版本相当于successors(),而degree报告in_degree和out_degree的总和,尽管有时可能感觉不一致。
>>> 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]
注意:一些算法只适用于有向图,而另一些算法则不适用于有向图。所以,将有向图和无向图混为一谈是十分危险的!!!。如果你想在某些度量中将有向图视为无向图,你应该使用graph . to_undirection()或者下述代码将其转换为无向图:
H = nx.Graph(G) # convert G to undirected graph
2.4Multigraphs (复杂的多重图)
NetworkX为允许任意一对节点之间有多条边的图提供了类。MultiGraph和MultiDiGraph类允许你添加相同的边两次,可能使用不同的边数据。对于某些应用程序,这可能非常强大,但是许多算法在这样的图上是不适用的。在这种图中只有某些函数可以用,例如MultiGraph.degree()。如果想用其它函数就需要将它转换成标准图,以使度量得到很好的定义。下面是一个例子:
>>> 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]
2.5 图生成器和图操作
除了按节点构造图或按边构造图外,还可以通过以下方法生成图:
- 使用图的类操作:
subgraph(G, nbunch) - induced subgraph view of G on nodes in nbunch
union(G1,G2) - graph union
disjoint_union(G1,G2) - graph union assuming all nodes are different
cartesian_product(G1,G2) - return Cartesian product graph
compose(G1,G2) - combine graphs identifying nodes common to both
complement(G) - graph complement
create_empty_copy(G) - return an empty copy of the same graph class
to_undirected(G) - return an undirected representation of G
to_directed(G) - return a directed representation of G
- 调用一个经典的小图表:
>>> petersen = nx.petersen_graph()
>>> tutte = nx.tutte_graph()
>>> maze = nx.sedgewick_maze_graph()
>>> tet = nx.tetrahedral_graph()
3.对经典图使用(构造)生成器,例如:
>>> K_5 = nx.complete_graph(5)
>>> K_3_5 = nx.complete_bipartite_graph(3, 5)
>>> barbell = nx.barbell_graph(10, 10)
>>> lollipop = nx.lollipop_graph(10, 20)
- 使用基于统计的生成器:
>>> er = nx.erdos_renyi_graph(100, 0.15)
>>> ws = nx.watts_strogatz_graph(30, 3, 0.1)
>>> ba = nx.barabasi_albert_graph(100, 5)
>>> red = nx.random_lobster(100, 0.9, 0.9)
5.从文件读取,文件应该是edge lists, adjacency lists, GML, GraphML, pickle, LEDA and others.
>>> nx.write_gml(red, "path.to.file")
>>> mygraph = nx.read_gml("path.to.file")
详细的生成器可以参考:
https://networkx.github.io/documentation/stable/reference/generators.html
2.6 图分析
生成的图G可以利用各种图论理论来进行分析,这里简要介绍一下,后面专门再写一篇:
>>> G = nx.Graph()
>>> G.add_edges_from([(1, 2), (1, 3)])
>>> G.add_node("spam") # adds node "spam"
>>> list(nx.connected_components(G))
[{1, 2, 3}, {'spam'}]
>>> sorted(d for n, d in G.degree()) #排序
[0, 1, 1, 2]
>>> nx.clustering(G) #聚类
{1: 0, 2: 0, 3: 0, 'spam': 0}
一些具有很大输出迭代量的函数在(节点、值)2元组上迭代。如果你愿意,可以很容易地将它们存储在dict结构中。
>>> sp = dict(nx.all_pairs_shortest_path(G))
>>> sp[3]
{3: [3], 1: [3, 1], 2: [3, 1, 2]}
这里给出算法相关连接:
https://networkx.github.io/documentation/stable/reference/algorithms/index.html
2.7 图的可视化
NetworkX主要不是一个图形绘制包,而是包含了Matplotlib的基本绘图以及使用开源Graphviz软件包的接口。这些是networkx的一部分。
首先需要导入:
>>> import matplotlib.pyplot as plt
使用下述函数之一测试是否导入networkx并绘制G:
>>> G = nx.petersen_graph()
>>> plt.subplot(121)
>>> nx.draw(G, with_labels=True, font_weight='bold')
>>> plt.subplot(122)
>>> nx.draw_shell(G, nlist=[range(5, 10), range(5)], with_labels=True, font_weight='bold')