networkx笔记

关于Python语言,如果没有接触过可以找一本Python的语法书来看看(推荐《Python 精要参考(第二版)》,网上有电子版)。这个语言很简单易学,只要有点编程基础,几天就可以学会它,然后就可以自如的运用它调用NetworkX了。

一、建立图或网络
1、无向图
在PythonWin 的Shell里输入:
import networkx as nx                            #导入NetworkX包,为了少打几个字母,将其重命名为nx
G = nx.Graph()                                        #建立一个空的无向图G
G.add_node(1)                                        #添加一个节点1
G.add_edge(2,3)                                     #添加一条边2-3(隐含着添加了两个节点2、3)
G.add_edge(3,2)                                     #对于无向图,边3-2与边2-3被认为是一条边
print G.nodes()                                       #输出全部的节点: [1, 2, 3]
print G.edges()                                       #输出全部的边:[(2, 3)]
print G.number_of_edges()                    #输出边的数量:1 
这样就可以建立一个简单的无向图了。如果你的数据是存在文件里的,可以循环从文件中读取节点和边添加到G中。
2、有向图
有向图的建立方式和无向图基本类似,只是在上述代码的第二行,将G = nx.Graph() 改为 G = nx.DiGraph() 。需要注意的是,此时再添加边3-2与边2-3,则被认为是两条不同的边(可以试着运行上述代码,自己查看结果)。
同时,有向图和无向图是可以相互转化的,分别用到Graph.to_undirected() 和 Graph.to_directed()两个方法。
3、加权图(网络)
有向图和无向图都可以给边赋予权重,用到的方法是add_weighted_edges_from,它接受1个或多个三元组[u,v,w]作为参数,其中u是起点,v是终点,w是权重。例如:
G.add_weighted_edges_from([(0,1,3.0),(1,2,7.5)])
添加0-1和1-2两条边,权重分别是3.0和7.5。
如果想读取权重,可以使用get_edge_data方法,它接受两个参数u和v,即边的起讫点。例如:
print G.get_edge_data(1,2)                   #输出{'weight': 7.5},这是一个字典结构,可以查看python语法了解它的用法。

三、调用图算法
NetworkX提供了常用的图论经典算法,例如DFS、BFS、最短路、最小生成树、最大流等等,非常丰富,如果不做复杂网络,只作图论方面的工作,也可以应用NetworkX作为基本的开发包。具体的算法调用方法我就不一一介绍了,可以浏览NX的在线手册http://networkx.lanl.gov/reference/algorithms.html,对每个算法都提供了详细的帮助文档和示例。下面只给出一个最短路算法的例子:
path=nx.all_pairs_shortest_path(G)     #调用多源最短路径算法,计算图G所有节点间的最短路径
print path[0][2]                                     #输出节点0、2之间的最短路径序列: [0, 1, 2]

四、小结
作为NetworkX学习笔记的第一部分,今天先简单介绍下NetworkX的安装与基本使用方法。后边有时间会陆续介绍:用NetworkX进行复杂网络拓扑结构统计指标计算、典型复杂网络建模(随机图、小世界、无标度等)以及复杂网络可视化的方法等,请感兴趣的朋友关注并提出批评与意见。

复杂网络分析库NetworkX学习笔记(2):统计指标计算

无论是实际网络还是对模型网络进行分析,都离不开对网络拓扑统计指标的计算。反映网络结构与动力学特性的统计指标有很多,Costa等的Characterization of Complex Networks: A Survey of measurements一文对此有全面的综述,本文仅介绍一些常用的统计指标在NetworkX中如何计算。
一、度、度分布
NetworkX可以用来统计图中每个节点的度,并生成度分布序列。下边是一段示例代码(这段代码可以在Shell里一行一行的输入,也可以将其保存为一个以py结尾的纯文本文件后直接运行),注意看注释部分:
import networkx as nx
G = nx.random_graphs.barabasi_albert_graph(1000,3)   #生成一个n=1000,m=3的BA无标度网络
print G.degree(0)                                   #返回某个节点的度
print G.degree()                                     #返回所有节点的度
print nx.degree_histogram(G)    #返回图中所有节点的度分布序列(从1至最大度的出现频次)

对上述结果稍作处理,就可以在Origin等软件里绘制度分布曲线了,当然也可以用matplotlib直接作图,在上述代码后接着输入:
import matplotlib.pyplot as plt                 #导入科学绘图的matplotlib包
degree =  nx.degree_histogram(G)          #返回图中所有节点的度分布序列
x = range(len(degree))                             #生成x轴序列,从1到最大度
y = [z / float(sum(degree)) for z in degree]  
#将频次转换为频率,这用到Python的一个小技巧:列表内涵,Python的确很方便:)
plt.loglog(x,y,color="blue",linewidth=2)           #在双对数坐标轴上绘制度分布曲线  
plt.show()                                                          #显示图表

二、群聚系数
这个在NetworkX里实现起来很简单,只需要调用方法nx.average_clustering(G) 就可以完成平均群聚系数的计算,而调用nx.clustering(G) 则可以计算各个节点的群聚系数。
三、直径和平均距离
nx.diameter(G)返回图G的直径(最长最短路径的长度),而nx.average_shortest_path_length(G)则返回图G所有节点间平均最短路径长度。
四、匹配性
这个也比较简单,调用 nx.degree_assortativity(G) 方法可以计算一个图的度匹配性。
五、中心性
这个我大部分不知道怎么翻译,直接上NX的帮助文档吧,需要计算哪方面的centrality自己从里边找:)
Degree centrality measures.(点度中心性?)
degree_centrality(G)     Compute the degree centrality for nodes.
in_degree_centrality(G)     Compute the in-degree centrality for nodes.
out_degree_centrality(G)     Compute the out-degree centrality for nodes.

Closeness centrality measures.(紧密中心性?)
closeness_centrality(G[, v, weighted_edges])     Compute closeness centrality for nodes.

Betweenness centrality measures.(介数中心性?)
betweenness_centrality(G[, normalized, ...])     Compute betweenness centrality for nodes.
edge_betweenness_centrality(G[, normalized, ...])     Compute betweenness centrality for edges.

Current-flow closeness centrality measures.(流紧密中心性?)
current_flow_closeness_centrality(G[, ...])     Compute current-flow closeness centrality for nodes.
Current-Flow Betweenness

Current-flow betweenness centrality measures.(流介数中心性?)
current_flow_betweenness_centrality(G[, ...])     Compute current-flow betweenness centrality for nodes.
edge_current_flow_betweenness_centrality(G)     Compute current-flow betweenness centrality for edges.

Eigenvector centrality.(特征向量中心性?)
eigenvector_centrality(G[, max_iter, tol, ...])     Compute the eigenvector centrality for the graph G.
eigenvector_centrality_numpy(G)     Compute the eigenvector centrality for the graph G.

Load centrality.(彻底晕菜~~~)
load_centrality(G[, v, cutoff, normalized, ...])     Compute load centrality for nodes.
edge_load(G[, nodes, cutoff])     Compute edge load.
六、小结
上边介绍的统计指标只是NetworkX能计算的指标中的一小部分内容,除此之外NetworkX还提供了很多(我还没有用到过的)统计指标计算方法,感兴趣的朋友可以去查NetworkX的在线帮助文档:http://networkx.lanl.gov/reference/index.html。对于加权图的统计指标计算,NetworkX似乎没有直接提供方法(也可能是我没找到),估计需要自己动手编制一些程序来完成。

复杂网络分析库NetworkX学习笔记(3):网络演化模型

NetworkX提供了4种常见网络的建模方法,分别是:规则图,ER随机图,WS小世界网络和BA无标度网络。本文首先介绍在NetworkX生成这些网络模型的方法,然后以BA无标度网络的建模为例,分析利用NetworkX进行复杂网络演化模型设计的基本思路,以便将来开发出我们自己的模型。同时这篇文章里还涉及到一点复杂网络可视化的方法(后边有时间会另文介绍网络可视化的方法)。

一、规则图

规则图差不多是最没有复杂性的一类图了,在NetworkX中,用random_graphs.random_regular_graph(d, n)方法可以生成一个含有n个节点,每个节点有d个邻居节点的规则图。下面是一段示例代码,生成了包含20个节点、每个节点有3个邻居的规则图:

import networkx as nx
import matplotlib.pyplot as plt
RG = nx.random_graphs.random_regular_graph(3,20)  #生成包含20个节点、每个节点有3个邻居的规则图RG
pos = nx.spectral_layout(RG)          #定义一个布局,此处采用了spectral布局方式,后变还会介绍其它布局方式,注意图形上的区别:
nx.draw(RG,pos,with_labels=False,node_size = 30)  #绘制规则图的图形,with_labels决定节点是非带标签(编号),node_size是节点的直径
plt.show()  #显示图形


这样,用短短的几行代码就完成了一个最基本的网络图形绘制,而且生成了一个功能丰富的窗体。窗口左下方的工具栏可以对图像进行放大、缩小、平移、保存等操作,可以自己动手试一下。同时,在源文件的目录下还生成了一个png格式的图片文件,可以把它插入报告或论文中,是不是很方便呢?
二、运用样式
上边的代码虽然简单,但生成的图形略显单调。NetworkX提供了一系列样式参数,可以用来修饰和美化图形,达到我们想要的效果。常用的参数包括:
      - `node_size`:  指定节点的尺寸大小(默认是300,单位未知,就是上图中那么大的点)
      - `node_color`:  指定节点的颜色 (默认是红色,可以用字符串简单标识颜色,例如'r'为红色,'b'为绿色等,具体可查看手册)
      - `node_shape`:  节点的形状(默认是圆形,用字符串'o'标识,具体可查看手册)
      - `alpha`: 透明度 (默认是1.0,不透明,0为完全透明) 
      - `width`: 边的宽度 (默认为1.0)
      - `edge_color`: 边的颜色(默认为黑色)
      - `style`: 边的样式(默认为实现,可选: solid|dashed|dotted,dashdot)
      - `with_labels`: 节点是否带标签(默认为True)
      - `font_size`: 节点标签字体大小 (默认为12)
      - `font_color`: 节点标签字体颜色(默认为黑色)
灵活运用上述参数,可以绘制不同样式的网络图形,例如:nx.draw(G,node_size = 30,with_labels = False) 是绘制节点尺寸为30、不带标签的网络图。
三、运用布局
NetworkX在绘制网络图形方面提供了布局的功能,可以指定节点排列的形式。这些布局包括:
circular_layout:节点在一个圆环上均匀分布
random_layout:节点随机分布
shell_layout:节点在同心圆上分布
spring_layout: 用Fruchterman-Reingold算法排列节点(这个算法我不了解,样子类似多中心放射状)
spectral_layout:根据图的拉普拉斯特征向量排列节点?我也不是太明白
布局用pos参数指定,例如:nx.draw(G,pos = nx.circular_layout(G))。在上一篇笔记中,四个不同的模型分别是用四种布局绘制的,可以到那里去看一下效果,此处就不再重复写代码了。
另外,也可以单独为图中的每个节点指定一个位置(x、y坐标),不过比较复杂,我还没有这样做过。感兴趣的朋友可以看一下NetworkX文档中的一个例子:http://networkx.lanl.gov/examples/drawing/knuth_miles.html
四、添加文本
用plt.title()方法可以为图形添加一个标题,该方法接受一个字符串作为参数,fontsize参数用来指定标题的大小。例如:plt.title("BA Networks", fontsize = 20)。如果要在任意位置添加文本,则可以采用plt.text()方法。事实上这些功能(包括前边的图形保存等功能)并不是由NetworkX提供的,从包的名字上可以看出,这些绘图函数都是由matplotlib这个包提供的。NetworkX只是把与复杂网络绘图相关的功能重新包装了一下,让用户调用更方便而已。
需要补充的一点是,matplotlib并不直接支持中文文本,如果想输出中文,走正规方法还是挺麻烦的(见http://blog.csdn.net/KongDong/archive/2009/07/10/4338826.aspx)。不过有聪明的网友提出了一种偷梁换柱的解决方案:换字体。只要把一个中文字体文件(ttf文件)更名为Vera.ttf,拷贝到matplotlib的字体目录中覆盖原有文件,就可以输出中文了,具体细节见http://hi.baidu.com/ucherish/blog/item/63155e52b68c90070df3e3ff.html 。
五、小结
这篇笔记简单介绍了用NetworkX绘制复杂网络图形的方法,实际上NetworkX的制图能力是很强的(主要是matplotlib的功劳),本文所介绍的功能只是其中最基础的一部分,更多功能还有待我们一起去发掘。再次推荐 http://networkx.lanl.gov/gallery.html上的绘图示例代码,能看懂弄清这些代码,用NetworkX绘图应该就难不住你了:)

复杂网络分析库NetworkX学习笔记(5):二分图

二分图又称二部图,是图论中的一种特殊模型,它的顶点可分割为两个互不相交的子集,并且图中的每条边所关联的两个顶点分别属于这两个不同的顶点集。二分图在复杂网络分析中有很多应用,例如科学家合作网络(作者和论文)、商品网络(商品和购买者)、城市公交网络(线路和站点)等都可以用二分图来进行描述。NetworkX提供了一些基本的二分图建模与分析功能,下面对这些功能作一个简单的介绍。
一、建立二分图
建立二分图与建立普通的图方法比较类似,需要注意的是,边只能在不同类节点之间添加,同类节点之间不要添加边就可以。下面是一个简单的例子(本例中用1开头的编号表示项目节点,用2开头的编号表示参与者节点):
import networkx as nx
B = nx.Graph()
#添加一个项目101,它有3个参与者:201,202,203
B.add_edge(101,201)
B.add_edge(101,202)
B.add_edge(101,203)
#添加一个项目102,它有2个参与者:203,202,2034
B.add_edge(102,203)
B.add_edge(102,204)
…………………………

此外,
NetworkX还提供了多种二分图演化模型的建立方法,在这里把它们列出来供大家参考:
--  networkx.generators.classic.complete_bipartite_graph(n1, n2, create_using=None)
建立一个完全二分图
--  networkx.generators.bipartite.bipartite_configuration_model (aseq, bseq, create_using=None, seed=None)
根据两个度序列建立一个二分图
--  networkx.generators.bipartite.bipartite_random_regular_graph(d, n, create_using=None, seed=None)
建立一个随机的规则二分图
--  networkx.generators.bipartite.bipartite_preferential_attachment_graph(aseq, p, create_using=None, seed=None)
建立一个优先连接的二分图
--  networkx.generators.bipartite.bipartite_havel_hakimi_graph(aseq, bseq, create_using=None)
根据两个度序列建立一个Havel-Hakimi模式的二分图(下面两个模型类似,我没有接触过这个模型,不太理解具体含义)
--  networkx.generators.bipartite.bipartite_reverse_havel_hakimi_graph(aseq, bseq, create_using=None)
--   networkx.generators.bipartite.bipartite_alternating_havel_hakimi_graph(aseq, bseq, create_using=None)
二、检测图的二分性
networkx.is_bipartite()方法可以检测一个图是否是二分图。例如对上边代码建立的二分图,nx.is_bipartite(B)返回的结果是True,而对一个随机图R = nx.random_graphs.gnp_random_graph(100,0.2),由于它不是二分图,nx.is_bipartite(R)返回的结果是False。
NetworkX并没有提供图的二分度计算方法,如果使用到这一功能需要自己编制代码。何大韧老师等编写的《复杂系统与复杂网络》一书的132页有二分度的计算公式,感兴趣的朋友可以自己实现这一程序。
此外,NetworkX还提供了对二分图节点进行着色的算法:networkx.bipartite_color(),它可以返回一个字典结构,分别为二分图中的两类节点赋予一个颜色值以示区别。例如对前面建立的二分图进行着色:print nx.bipartite_color(B),将返回结果 :{101: 1, 102: 1, 201: 0, 202: 0, 203: 0, 204: 0},项目节点被赋予颜色值1,参与者节点的颜色值是0。可以用这个值来检测节点类型,也可以用它来进行绘图(参看第4篇笔记《网络可视化》)。
三、二分图的投影
二分图可以通过向参与者节点投影或向项目节点投影转换为一个单分图(见下图),NetworkX提供的networkx.project(B, nodes)方法可以完成这一工作。它接受两个参数:一个是二分图B,另一个是投向的节点集合nodes。

二分图投影示意(向下投影)
对于节点集合的提取可以用networkx.bipartite_sets方法,它可以将一个二分图的两类节点提取为两个集合(X,Y),其中X是项目节点,Y是参与者节点。下面是一段示例代码,演示上述两个函数的用法:
(接第一节的代码之后)
NSet = nx.bipartite_sets(B)   #将二分图中的两类节点分别提取出来
Act = nx.project(B,NSet[0])     #向项目节点投影
Actor = nx.project(B,NSet[1])  #向参与者节点投影
print Act.edges()  #输出 [(101, 102)]
print Actor.edges()   #输出 [(201, 202), (201, 203), (202, 203), (203, 204)]

四、通过派系提取构造二分图
对于一个存在派系(Clique)的图,可以通过提取派系结构生成一个二分图。NetworkX提供的networkx.make_clique_bipartite方法可以从图中查找派系,然后将一个派系作为一个项目节点并和该派系中的节点建立连接,从而构造一个二分图。它是二分图向参与者节点投影的逆过程,下边是一段示例代码:
(接第三节的代码之后)
G = nx.make_clique_bipartite(Actor)
print G.edges()  #输出:[(201, -1), (202, -1), (203, -2), (203, -1), (204, -2)]

补充一点,NetworkX的派系提取算法据说效率很高,不过我没有做过这方面的东西,感兴趣的朋友可以去看它的源代码(见http://networkx.lanl.gov/reference/algorithms.clique.html)。
五、小结
本篇笔记介绍了用NetworkX进行二分图建模与分析的方法,到今天为止,我的《NetworkX学习笔记》就暂告一段落了。我目前的工作中只用到了这几篇笔记中所写的功能,以后如果有其他的心得体会我还会继续进行补充。希望这些文章对学习和研究复杂网络的朋友们能起到一点帮助作用,也欢迎各位留言批评、讨论。
最后,向NetworkX的三位开发者Aric Hagberg、Dan Schult 、Pieter Swart 以及许许多多的贡献者致敬*,感谢他们为我们提供了这样一个优秀的复杂网络分析工具!
根据三位开发者的建议,如果要在论文中引用NetworkX,请引用以下文献:
Aric A. Hagberg, Daniel A. Schult and Pieter J. Swart, “Exploring network structure, dynamics, and function using NetworkX”, in Proceedings of the 7th Python in Science Conference (SciPy2008), Gäel Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11–15, Aug 2008

I got exactly the same error message. And it seams there are many many possible causes. In my case, I solved the issue by reinstalling six

pip uninstall six ; pip install six
发布了392 篇原创文章 · 获赞 492 · 访问量 241万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览