Python NetworkX图论库:从基础构建到PageRank算法实战

闻溪
闻溪
发布时间:2026-10-13 | 5人浏览过
原创

本文详细介绍Python中NetworkX库的核心功能,涵盖无向图与有向图的创建、顶点与边的属性管理、图的遍历算法(DFS/BFS)及可视化绘制。重点解析PageRank算法原理与参数配置,通过代码示例演示如何计算节点重要性,适用于社会网络分析与复杂系统建模。

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),则返回NodeDataView对象,包含每个顶点的ID及其他属性。


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

添加顶点时,可同时指定自定义属性,例如名称或权重:


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

2、查看顶点的属性

通过_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

adj返回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

顶点由顶点ID及其属性构成。


>>> 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

五、图的遍历

图遍历指沿边从任一顶点出发,对图中所有顶点访问且仅访问一次。根据优先顺序不同,通常分为深度优先搜索(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值

每个顶点的PageRank(PR)值代表访问该顶点的概率,可通过networkx.pagerank()函数计算。该函数根据顶点的入边及边的权重计算PR值,即PR值与顶点的入边及其weight(权重)属性相关:


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

常用参数注释:

  • g:无向图将被转换为有向图,一条无向边转换为两条有向边;
  • alpha:阻尼参数,默认值0.85,取值范围0到1,代表从图中某特定点指向其他任意点的概率;
  • 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 networkx 包绘制复杂网络关系图

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

python之networkx库小结

python复杂网络分析库NetworkX

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表