Python 学习 第十六篇:networkx

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对象,

五,图的遍历

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

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,图的遍历

示例代码,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

使用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时,需要传递一个无向图g,使用networkx模块中的pagerank()函数,生成的图中,每个顶点都有特定的PageRank值。

pr=nx.pagerank(g)
page_rank_value=pr[node]

1,创建无向图

在创建无向图之后,向图中增加节点和边

g=nx.Graph()
#向无向图中添加节点a和节点d,且a,d之间有一条连边
g.add_edge(‘a‘,‘d‘)  
g.add_edge(‘b‘,‘d‘)
g.add_edge(‘c‘,‘d‘)
g.add_edge(‘c‘,‘f‘)
g.add_edge(‘d‘,‘e‘)
g.add_edge(‘d‘,‘f‘)
g.add_edge(‘e‘,‘f‘)

2,创建PageRank

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

pr=nx.pagerank(g)
for node, pageRankValue in pr.items():
    print("%s,%.4f" %(node,pageRankValue))

参考文档:

python networkx 包绘制复杂网络关系图

社会网络分析与挖掘---Python之networkx介绍

python之networkx库小结

python复杂网络分析库NetworkX

原文地址:https://www.cnblogs.com/ljhdo/p/10662902.html

时间: 2024-10-07 06:11:06

Python 学习 第十六篇:networkx的相关文章

Python学习第十六篇——异常处理

在实际中,很多时候时候,我们并不能保证我们所写的程序是完美的.比如我们程序的本意是:用户在输入框内输入数字,并进行后续数学运算,即使我们提醒了用户需要输入数字而不是文本,但是有时会无意或者恶意输入字符串等我们意料之外的东西,但我们又不想让我们的程序崩溃,Python引入了一种"异常处理"机制,使得我们能够正确的处理这种意外: 比如下面这段代码:想读取文件的内容,但假如所要读取的文件不存在应该怎么办: 1 def file_read(filename): 2 try: 3 with op

python学习[第十二篇] 数据类型之 集合

python学习[第十二篇] 数据类型之 集合 集合概念 python中集合是一组无序排列的哈希值.集合分为两种可变集合(set)和不可变集合(frozenset) 对可变集合可以修改和删除元素,对于不可变集合不允许.可变集合是不可以哈希的,因此既不能用作字典的键,也不能做其他集合的元素. 集合的增删改查 集合的创建于赋值 集合与列表([]) 和字典({})不同,集合没有特别的语法格式.列表和字典可以通过他们自己的工厂方法创建,这也是集合的唯一的创建方式.set()和frozenset() #创

[Python笔记]第十六篇:web框架之Tornado

Tornado是一个基于python的web框架,xxxxx 安装 python -m pip install tornado 第一个Tornado程序 安装完毕我们就可以新建一个app.py文件,放入下面的代码直接运行就可以了,然后在浏览器访问127.0.0.1:8888 import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.writ

python学习笔记十六 django深入学习一

django 请求流程图 django 路由系统 在django中我们可以通过定义urls,让不同的url路由到不同的处理函数 from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), #精确匹配 url(r'^articles/([0-9]{4})/$', views.year_archive), #动态路由 url(r'^articles/([0-9]{4})/([0-9]{2

Python学习(十六)内置函数,递归

1.递归 def test1(): num=int(input('输入数字')) if num%2==0: #判断输入数字是不是偶数 return True #是偶数,程序退出,返回true print('不是偶数请重新输入') return test1() #不是偶数的话继续调用自己,输入值 print(test1()) 递归的效率不高,最多递归999次 2.内置函数 python自带的函数 id()#看内存地址type()#看数据类型print()#打印input()#输入list() #转

Python学习笔记十六_模块结构调整

一.什么是模块结构调整 当一个脚本中有大量的配置.方法及接口时,脚本往往显得十分臃肿.为了代码更易读,可以将一个繁杂的脚本根据不同的功能放在不同的文件夹中分类管理,即模块结构调整. 二.模块结构调整实例 下面根据一个具体的例子来看一下如何拆分调整代码 1.根据正常人的思维写代码完成功能 代码需求: (1) 注册接口: (a) 写一个注册接口,密码存成密文 (b) 数据存到redis,redis的key用string类型 (c) Amy  7869d295e566295b51eec5d6bed67

Python 学习日记第六篇 -- 深浅拷贝

深浅拷贝: 1.字符串和数字 import copy #浅拷贝 copy.copy() #深拷贝 copy.deepcopy() ###################################################################################### a1 = "string" #a1 = 11 a2 = a1 a3 = copy.copy(a1) a4 = copy.deepcopy(a1) print(id(a1)) print(

python学习笔记(十六) - ORM框架(SQLAlchemy)

所谓的ORM就是Object-Relational Mapping,把关系数据库的表结果映射到对象上. 1. 安装SQLAlchemy: easy_install sqlalchemy 2. 导入SQLAlchemy,并初始化DBSession: # 导入: from sqlalchemy import Column, String, create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declara

Python学习【第六篇】运算符

运算符 算数运算: 1 a = 21 2 b = 10 3 c = 0 4 5 c = a + b 6 print ("1 - c 的值为:", c) 7 8 c = a - b 9 print ("2 - c 的值为:", c) 10 11 c = a * b 12 print ("3 - c 的值为:", c) 13 14 c = a / b 15 print ("4 - c 的值为:", c) 16 17 c = a %