Python 学习教程之networkx


Posted in Python onApril 15, 2019

networkx是Python的一个包,用于构建和操作复杂的图结构,提供分析图的算法。图是由顶点、边和可选的属性构成的数据结构,顶点表示数据,边是由两个顶点唯一确定的,表示两个顶点之间的关系。顶点和边也可以拥有更多的属性,以存储更多的信息。

对于networkx创建的无向图,允许一条边的两个顶点是相同的,即允许出现自循环,但是不允许两个顶点之间存在多条边,即出现平行边。边和顶点都可以有自定义的属性,属性称作边和顶点的数据,每一个属性都是一个Key:Value对。

一,创建图

在创建图之前,需要导入networkx模块,通常设置别名为nx;如果创建的图中,顶点之间的边没有方向,那么该图称作无向图。在创建图时,可以通过help(g)来获得图的帮助文档。

import networkx as nx

g=nx.Graph()#创建空的无向图
g=nx.DiGraph()#创建空的有向图

二,图的顶点

图中的每一个顶点Node都有一个关键的ID属性,用于唯一标识一个节点,ID属性可以整数或字符类型;顶点除了ID属性之外,还可以自定义其他的属性。

1,向图中增加顶点

在向图中增加顶点时,可以一次增加一个顶点,也可以一次性增加多个顶点,顶点的ID属性是必需的。在添加顶点之后,可以通过g.nodes()函数获得图的所有顶点的视图,返回的实际上NodeView对象;如果为g.nodes(data=True)的data参数设置为true,那么返回的是NodeDataView对象,该对象不仅包含每个顶点的ID属性,还包括顶点的其他属性。

g.add_node(1)
g.add_nodes_from([2,3,4])
g.nodes()
#NodeView((1, 2,3,4))

在向图中添加顶点时,除ID属性之外,也可以向顶点中增加自定义的属性,例如,名称属性,权重属性:

>>> g.add_node(1,name='n1',weight=1)
>>> g.add_node(2,name='n2',weight=1.2)

2,查看顶点的属性

通过属性_node获得图的所有顶点和属性的信息,_node属性返回的是一个字典结构,字典的Key属性是顶点的ID属性,Value属性是顶点的其他属性构成的一个字典。

>>> g._node
{1: {'name': 'n1', 'weight': 1}, 2: {'name': 'n2', 'weight': 1.2}, 3: {}, 4: {}}
>>>g.nodes(data=True)

可以通过顶点的ID属性来查看顶点的其他属性:

>>> g.node[1]
{'name': 'n1', 'weight': 1}
>>> g.node[1]['name']
'n1 new'

通过g.nodes(),按照特定的条件来查看顶点:

>>> list(g.nodes(data=True))
 [(1, {'time': '5pm'}), (3, {'time': '2pm'})]

3,删除顶点

通过remove函数删除图的顶点,由于顶点的ID属性能够唯一标识一个顶点,通常删除顶点都需要通过传递ID属性作为参数。

g.remove_node(node_ID)
g.remove_nodes_from(nodes_list)

4,更新顶点

更新图的顶点,有两种方式,第一种方式使用字典结构的_update函数,第二种方式是通过索引来设置新值:

>>> g._node[1].update({'name':'n1 new'})
>>> g.node[1]['name']='n1 new'
{1: {'name': 'n1 new', 'weight': 1}, 2: {'name': 'n2', 'weight': 1.2}, 3: {}, 4: {}}

5,删除顶点的属性

使用del命令删除顶点的属性

del g.nodes[1]['room']

6,检查是否存在顶点

检查一个顶点是否存在于图中,可以使用 n in g方式来判断,也可以使用函数:

g.has_node(n)

三,图的边

图的边用于表示两个顶点之间的关系,因此,边是由两个顶点唯一确定的。为了表示复杂的关系,通常会为边增加一个权重weight属性;为了表示关系的类型,也会设置为边设置一个关系属性。

1,向图中增加边

边是由对应顶点的名称构成的,例如,顶点2和3之间有一条边,记作e=(2,3),通过add_edge(node1,node2)向图中添加一条边,也可以通过add_edges_from(list)向图中添加多条边;在添加边时,如果顶点不存在,那么networkx会自动把相应的顶点加入到图中。

g.add_edge(2,3)
g.add_edges_from([(1,2),(1,3)])
g.edges()
#EdgeView([(1, 2), (1, 3), (2, 3)])

可以向边中增加属性,例如,权重,关系等:

g.add_edge(1, 2, weight=4.7, relationship='renew')

由于在图中,边的权重weight是非常有用和常用的属性,因此,networkx模块内置以一个函数,专门用于在添加边时设置边的权重,该函数的参数是三元组,前两个字段是顶点的ID属性,用于标识一个边,第三个字段是边的权重:

g.add_weighted_edges_from([(1,2,0.125),(1,3,0.75),(2,4,1.2),(3,4,0.375)])

在增加边时,也可以一次增加多条边,为不同的边设置不同的属性:

g.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])

2,查看边的属性

查看边的属性,就是查看边的数据(data),查看所有边及其属性:

>>> g.edges(data=True)
EdgeDataView([(1, 2, {}), (1, 3, {}), (2, 3, {})])

查看特定的边的信息有两种方式:

>>> g[1][2]
>>> g.get_edge_data(1,2)
{'weight': 0.125, 'relationship': 'renew', 'color': 'blue'}

3,删除边

边是两个顶点的ID属性构成的元组,通过 edge=(node1,node2) 来标识边,进而从图中找到边:

g.remove_edge(edge)
g.remove_edges_from(edges_list)

4,更新边的属性

通过边来更新边的属性,由两种方式,一种是使用update函数,一种是通过属性赋值来实现:

g[1][2]['weight'] = 4.7
g.edge[1][2]['weight'] = 4
g[1][2].update({"weight": 4.7})
g.edges[1, 2].update({"weight": 4.7})

5,删除边的属性

通过 del命令来删除边的属性

del g[1][2]['name']

6,检查边是否存在

检查一条边是否存在于图中

g.has_edge(1,2)

四,图的属性

图的属性主要是指相邻数据,节点和边。

1,adj

ajd返回的是一个AdjacencyView视图,该视图是顶点的相邻的顶点和顶点的属性,用于显示用于存储与顶点相邻的顶点的数据,这是一个只读的字典结构,Key是顶点,Value是顶点的属性数据。

>>> g.adj[1][2]
{'weight': 0.125, 'relationship': 'renew', 'color': 'blue'}
>>> g.adj[1]
AtlasView({2: {'weight': 0.125, 'relationship': 'renew', 'color': 'blue'}, 3: {'weight': 0.75}})

2,edges

图的边是由边的两个顶点唯一确定的,边还有一定的属性,因此,边是由两个顶点和边的属性构成的:

>>> g.edges
EdgeView([(1, 2), (1, 3), (2, 3), (2, 4), (3, 4)])
>>> g.edges.data()
EdgeDataView([(1, 2, {'weight': 0.125, 'relationship': 'renew', 'color': 'blue'}), 
(1, 3, {'weight': 0.75}), 
(2, 3, {'weight': 8}), 
(2, 4, {'weight': 1.2}), 
(3, 4, {'weight': 0.375})])

EdgeView仅仅提供边的信息,可以通过属性g.edges或函数g.edges()来获得图的边视图。

EdgeDataView提供图的边和边的属性,可以通过EdgeView对象来调用data()函数获得。

3,nodes

图的顶点是顶点和顶点的属性构成的

>>> g.nodes
NodeView((1, 2, 3, 4))
>>> g.nodes.data()
NodeDataView({1: {'name': 'n1 new', 'weight': 1}, 2: {'name': 'n2', 'weight': 1.2}, 3: {}, 4: {}})

NodeView 通过属性g.nodes或函数g.nodes()来获得。

NodeDataView提供图的边和边的属性,可以通过NodeView对象来调用data()函数获得。

4,degree

对于无向图,顶点的度是指跟顶点相连的边的数量;对于有向图,顶点的图分为入度和出度,朝向顶点的边称作入度;背向顶点的边称作出度。

通过g.degree 或g.degree()能够获得DegreeView对象,

五,图的遍历

图的遍历是指按照图中各顶点之间的边,从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次。图的遍历按照优先顺序的不同,通常分为深度优先搜索(DFS)和广度优先搜索(BFS)两种方式。

1,查看顶点的相邻顶点

查看顶点的相邻顶点,有多种方式,例如,以下代码都用于返回顶点1的相邻顶点,g[n]表示图g中,与顶点n相邻的所有顶点:

g[n]
g.adj[n]
g.neighbors(n)

其中,g.neighbors(n)是g.adj[n]的迭代器版本。

2,查看图的相邻

该函数返回顶点n和相邻的节点信息:

>>> for n, nbrs in g.adjacency():
...   print(n)
...   print(nbrs)

3,图的遍历

深度优先遍历的算法:

首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的相邻顶点;
当当前顶点没有未访问过的相邻顶点时,则回到上一个顶点,继续试探别的相邻顶点,直到所有的顶点都被访问过。
深度优先遍历算法的思想是:从一个顶点出发,一条路走到底;如果此路走不通,就返回上一个顶点,继续走其他路。

广度优先遍历的算法:

从顶点v出发,依次访问v的各个未访问过的相邻顶点;

分别从这些相邻顶点出发依次访问它们的相邻顶点;

广度优先遍历算法的思想是:以v为起点,按照路径的长度,由近至远,依次访问和v有路径相通且路径长度为1,2...,n的顶点。

在进行图遍历时,需要访问顶点的相邻顶点,这需要用到adjacency()函数,例如,g是一个无向图,n是顶点,nbrs是顶点n的相邻顶点,是一个字典结构

for n,nbrs in g.adjacency(): 
  print (n, nbrs)
  for nbr,attr in nbrs.items():
    # nbr表示跟n连接的顶点,attr表示这两个点连边的属性集合
    print(nbr,attr)

六,绘制Graph

使用networkx模块draw()函数构造graph,使用matplotlib把图显示出来:

nx.draw(g)
import matplotlib.pyplot as plt
plt.show()

修改顶点和边的颜色:

g = nx.cubical_graph()
nx.draw(g, pos=nx.spectral_layout(g), nodecolor='r', edge_color='b')
plt.show()

完整的示例如下面的代码所示:

from matplotlib import pyplot as plt
import networkx as nx
g=nx.Graph()
g.add_nodes_from([1,2,3])
g.add_edges_from([(1,2),(1,3)])
nx.draw_networkx(g)
plt.show()

七,计算每个顶点的PageRank值

在计算每个顶点的PageRank(简称PR)值时,可以使用networkx模块中的pagerank()函数,该函数根据顶点的边和边的权重来计算顶点的PR值:

pagerank(g, alpha=0.85, personalization=None, max_iter=100, tol=1e-06, nstart=None, weight='weight', dangling=None)

常用的参数注释:

g:无向图会被转换为有向图,一条无向边转换为两条又向边

alpha:阻尼参数,默认值是0.85

weight:默认值是weight,表示使用edge的weight属性作为权重,如果没有指定,那么把edge的权重设置为1;

1,举个例子

例如,创建一个有向图,由三个顶点(A、B和C),两条边(A指向B,A指向C),边的权重都是0.5

g=nx.DiGraph()
g.add_weighted_edges_from([('A','B',0.5),('A','C',0.5)])
print( nx.pagerank(g))
#{'A': 0.259740259292235, 'C': 0.3701298703538825, 'B': 0.3701298703538825}

修改边的权重,并查看顶点的PR值:

g['A']['C']['weight']=1
print( nx.pagerank(g))  
# {'A': 0.259740259292235, 'C': 0.40692640737443164, 'B': 0.3333333333333333}

2,查看各个顶点的PR值

根据图来创建PageRank,并查看各个顶点的PageRank值

pr=nx.pagerank(g)
#page_rank_value=pr[node]
for node, pageRankValue in pr.items():
  print("%s,%.4f" %(node,pageRankValue))
Python 相关文章推荐
Python使用metaclass实现Singleton模式的方法
May 05 Python
轻松实现python搭建微信公众平台
Feb 16 Python
详解python中的Turtle函数库
Nov 19 Python
python基于itchat模块实现微信防撤回
Apr 29 Python
利用pyinstaller打包exe文件的基本教程
May 02 Python
Python中模块(Module)和包(Package)的区别详解
Aug 07 Python
Flask框架学习笔记之表单基础介绍与表单提交方式
Aug 12 Python
简单了解django文件下载方式
Feb 10 Python
Python爬虫JSON及JSONPath运行原理详解
Jun 04 Python
Python 开发工具通过 agent 代理使用的方法
Sep 27 Python
python中sqllite插入numpy数组到数据库的实现方法
Jun 21 Python
Python基本的内置数据类型及使用方法
Apr 13 Python
Python OS模块实例详解
Apr 15 #Python
Python日期时间Time模块实例详解
Apr 15 #Python
Python3.6中Twisted模块安装的问题与解决
Apr 15 #Python
python使用BeautifulSoup与正则表达式爬取时光网不同地区top100电影并对比
Apr 15 #Python
Python Datetime模块和Calendar模块用法实例分析
Apr 15 #Python
Python如何处理大数据?3个技巧效率提升攻略(推荐)
Apr 15 #Python
Python利用lxml模块爬取豆瓣读书排行榜的方法与分析
Apr 15 #Python
You might like
杏林同学录(七)
2006/10/09 PHP
比较全的PHP 会话(session 时间设定)使用入门代码
2008/06/05 PHP
php的日期处理函数及uchome的function_coomon中日期处理函数的研究
2011/01/12 PHP
php将图片保存为不同尺寸图片的图片类实例
2015/03/30 PHP
通过JAVAScript实现页面自适应
2007/01/19 Javascript
CCPry JS类库 代码
2009/10/30 Javascript
JavaScript 内置对象属性及方法集合
2010/07/04 Javascript
Array, Array Constructor, for in loop, typeof, instanceOf
2011/09/13 Javascript
javascript 获取模态窗口的滚动位置代码
2013/08/06 Javascript
动态标签 悬停效果 延迟加载示例代码
2013/11/21 Javascript
JavaScript中创建对象和继承示例解读
2014/02/12 Javascript
基于JavaScript实现类似于百度学术高级检索功能
2016/03/02 Javascript
浅谈JavaScript 标准对象
2016/06/02 Javascript
bootstrap confirmation按钮提示组件使用详解
2017/08/22 Javascript
微信小程序wx.request实现后台数据交互功能分析
2017/11/25 Javascript
vue 设置proxyTable参数进行代理跨域
2018/04/09 Javascript
WebSocket的通信过程与实现方法详解
2018/04/29 Javascript
Vue项目从webpack3.x升级webpack4不完全指南
2019/04/28 Javascript
Vue+ElementUI table实现表格分页
2019/12/14 Javascript
React+EggJs实现断点续传的示例代码
2020/07/07 Javascript
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
Python标准库之循环器(itertools)介绍
2014/11/25 Python
python中xrange用法分析
2015/04/15 Python
自动化Nginx服务器的反向代理的配置方法
2015/06/28 Python
Python实现的生产者、消费者问题完整实例
2018/05/30 Python
使用Python监视指定目录下文件变更的方法
2018/10/15 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
2020/06/10 Python
Django如何在不停机的情况下创建索引
2020/08/02 Python
Python实现石头剪刀布游戏
2021/01/20 Python
聪明的粉丝购买门票的地方:TickPick
2018/03/09 全球购物
SIXPAD智能健身仪英国官网:革命性的训练装备品牌
2018/09/27 全球购物
工程售后服务承诺书
2014/05/21 职场文书
中学生运动会口号
2014/06/07 职场文书
派出所班子党的群众路线对照检查材料思想汇报
2014/10/01 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
Python实现日志实时监测的示例详解
2022/04/06 Python