networkx学习笔记
安装
以前在需要使用代码绘制复杂网络中的图时,使用过igraph,但是igraph的安装配置十分的麻烦,安装了anaconda之后也不能使用,所以转而使用networkx。安装了anaconda之后无需在进行任何其他的配置就可以使用。
创建一个图graph
创建一个没有连边和节点的图
import networkx as nx
G = nx.Graph()
根据定义,图是节点以及节点之间的连边的集合。在networkx中,节点可以是任何哈希对象,例如文本字符串,图像,XML对象,另一个图,或者用户定义的对象。
节点Nodes
图G的产生方式有很多种,networkx自带了多种图生成函数,并且方便用户自由的读写各种形式的图。我们从简单的操作开始,一次向图中添加一个节点。
G.add_node(1)
或者我们可以向图中添加一个list对象
G.add_nodes_from([2, 3])
边Edges
图可以通过添加边来构建
G.add_edge(1, 2)
e = (2, 3)
G.add_edge(*e)
或者是通过添加边的列表来构建
G.add_edges_from([(1, 2), (2, 3)])
或者可以通过添加边的ebunch对象,ebunch是任何边元组的可以迭代的容器。边元组合的形式可以是有一对节点组成的2元组或者是一对节点外加边的属性字典组成的3元组。例如(2, 3, {‘weight’:6})
可是使用如下的方法销毁图对象:Graph.remove_node(),Graph.remove_nodes_from(), Graph.remove_edge(),Graph.remove_from()
添加已存在的边或者是节点是不会出现冲突的,例如,我们将上面建立的图清空。
G.clear()
然后我们添加一些新的节点或者是边
G.add_edges_from([(1,2), (1, 3)])
G.add_node(1)
G.add_edge(1, 2)
G.add_node("spam")
G.add_nodes_from("spam") # adds 4 nodes: 's', 'p', 'a', 'm'
这时,网络中包含8个节点,2条边
G.number_of_nodes()
8
G.number_of_edges()
2
G.nodes()
[1, 2, 3, 's', 'm', 'a', 'p', 'spam']
G.edges()
[(1, 2), (1, 3)]
G.neighbors(1)
[2, 3]
删除节点或者是边的语法相似
G.remove_nodes_from("spam")
G.nodes()
[1, 2, 3, 'spam']
G.remove_edge(1, 3)
G.edges()
[(1, 2)]
What to use as nodes and edges
因为节点和边没有被指定为Networks对象,这使得我们可以自由的使用有意义的对象来作为节点和边。通常我们会使用数字或者是字符串,但其实节点可以是任意的哈希对象,边可以使用如下的方法和任意的对象x进行绑定,G.add_edeg(n1,n2, object=x)
在这里,n1和n2可以是指RCSB蛋白数据库中的蛋白对象,x可以是从实验中得到的关于它们之间相互关系的一个详细的XML记录
我们发现这种能力非常有用,但如果不熟悉Python,它的滥用可能会带来意想不到的惊喜。如果有疑问,可以考虑使用convert_node_labels_to_integers()获得使用整数标签的更为传统的图
除了Graph.nodes(),Graph.edges()和Graph.neighbors(),迭代类的函数可以让你在只是想要遍历它们的时候不必要创建一个大的list。
使用下标也可以快速的访问图的数据结构。
G[1]
{2: {}, 3: {'color': 'blue'}}
G[1][2]
{}
当边已经存在的时候,可是使用下标来设置边的属性
G.add_edge(1, 3)
G[1][3]['color']='blue'
G[1][2]['weight']='2'
G[1] # information about node 1
{2: {'weight': '2'}, 3: {'color': 'blue'}}
G[2] # information about node 2
{1: {'weight': '2'}}
使用如下的方法可以快速遍历网络的检测出网络中权重小于0.5的边的信息
FG = nx.Graph()
FG.add_weighted_edges_from([(1, 2, 0.125),(1, 3, 0.75),(2, 3, 1.2),(3, 4, 0.275)])
for n,nbrs in FG.adjacency_iter():
for nbr, eattr in nbrs.items():
data = eattr['weight']
if data < 0.5:
print('(%d, %d, %.3f)' % (n, nbr, data))
(1, 2, 0.125)
(2, 1, 0.125)
(3, 4, 0.275)
(4, 3, 0.275)
添加图,节点以及边的属性
属性,如权重、标签、颜色或任何Python对象,都可以附加到图形、节点或边上
图的属性
G = nx.Graph(day="friday")
G.graph
{'day': 'friday'}
之后可以修改图的属性
G.graph['day']='Monday'
G.graph
{'day': 'Monday'}
节点的属性
添加节点属性的方法有:add_node(), add_nodes_from(), G.node()
G.add_node(1, time='5pm')
G.add_nodes_from([3], time='2pm')
G.node[1]
{'time': '5pm'}
G.node[3]
{'time': '2pm'}
G.node[1]['room'] = 714
G.node[1]
{'room': 714, 'time': '5pm'}
G.nodes(data=True)
[(1, {'room': 714, 'time': '5pm'}), (3, {'time': '2pm'})]
G.node[1]['room']=233 # 修改节点的属性
G.node[1]
{'room': 233, 'time': '5pm'}
边的属性
添加边的属性的方法有:add_edge(), add_edges_from(), G.edge(),或者是下标
G.add_edge(1, 2, weight=3.5)
G.add_edges_from([(3, 4), (4, 5)], color='red')
G.add_edges_from([(1, 2, {'color':'blue'}), (2, 3, {'weight':8})])
G.edge[1][2]['weight'] = 4.7
G.edge[1][2]['label'] = 'source'
G[1][2]
{'color': 'blue', 'label': 'source', 'weight': 4.7}
图生成器和图操作
除了上述的方法来构造一个图之外,还可以通过以下方式来构造图
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)
统计分析
G = nx.Graph()
G.add_edges_from([(1, 2), (1, 3)])
G.add_node('spam') # add a node 'spam'
sorted(nx.degree(G).values())
[0, 1, 1, 2]
nx.clustering(G)
{1: 0.0, 2: 0.0, 3: 0.0, 'spam': 0.0}
nx.degree(G)
{1: 2, 2: 1, 3: 1, 'spam': 0}
nx.degree(G, 1)
2
G.degree(1)
2
G.degree([1, 2])
{1: 2, 2: 1}
绘制
首先导入matplotlib接口
import matplotlib.pyplot as plt
ba=nx.barabasi_albert_graph(30,3)
nx.draw(ba,pos=nx.fruchterman_reingold_layout(ba))
plt.show()
例子
计算一个网络中节点的pagerank值
import matplotlib.pyplot as plt
import networkx as nx
G=nx.barabasi_albert_graph(30,3)
plt.figure(1)
nx.draw(G, pos=nx.shell_layout(G), node_color='y')
pr=nx.pagerank(G,alpha=0.85)
plt.figure(2)
nx.draw(G, pos=nx.shell_layout(G), node_size=[x * 18000 for x in pr.values()],node_color='r',with_labels=True)
plt.show()
networkx网站地址
http://networkx.readthedocs.io/en/networkx-1.11/overview.html