python networkx 复杂网络分析应用

文章目录

  • networkx简单介绍
  • networkx基本操作
    • 节点(Nodes)
    • 边(Nodes)
    • 节点与边的属性信息
    • 节点与边的其他操作
    • 图的遍历操作
    • 有向图与度
    • 其他生成图的方式
  • networkx简单应用
  • networkx进阶应用
    • 有向随机图
    • Watts–Strogatz小世界图
    • Girvan-Newman算法社区检测算法

更多内容请查看官方文档,以下内容参考
https://networkx.github.io/

networkx简单介绍

networkX是一个Python包,用于创建、操作和研究复杂网络的结构、动态和功能。
安装只需在控制台使用pip安装即可,问题不大。

pip install networkx

不过复杂网络毕竟还是要可视化的,这边建议您同时使用python图形库matplotlib

import networkx as nx
import matplotlib.pyplot as plt

networkx基本操作

根据图的定义,图是节点的集合,并且节点间有依赖关系(边)。
在NetworkX中,节点可以是任何可刷新的对象,如文本字符串、图像、XML对象、另一个图(Graph)、自定义节点对象等。

使用如下代码,即可生成一个图。

G = nx.Graph() 

节点(Nodes)

使用如下代码,即可生成包含三个节点的图,当然没有边连接的图就看起来特别搞笑。

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph() #生成图

G.add_node(1) #添加一个节点
G.add_nodes_from([2, 3]) #添加列表里的节点

#可视化
nx.draw(G)
plt.show()

边(Nodes)

直接定义边连接,无需重新定义节点。

import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph() #生成图

G.add_edge(1, 2) #添加一条边
G.add_edges_from([(1, 3), (2, 3)]) #添加列表里的边

#可视化
nx.draw(G)
plt.show()

节点与边的属性信息

如下代码可以为图、节点、边添加属性信息。

import networkx as nx
import matplotlib.pyplot as plt

#为图添加属性
G = nx.Graph(day="Friday")
print(G.graph)

#为节点添加属性
G.add_node(1, time='5pm')
G.add_nodes_from([3], time='2pm')
print(G.nodes[1])
G.nodes[1]['room'] = 714
print(G.nodes.data())

#为边添加属性
G.add_edges_from([(1, 2), (1, 3)])
print(G.edges[1, 2]) 

G.edges[1, 2]['color'] = "red" #为边添加属性
print(G.edges[1, 2]) 
>>> {'day': 'Friday'}
>>> {'time': '5pm'}
>>> NodeDataView({1: {'time': '5pm', 'room': 714}, 3: {'time': '2pm'}})
>>> {}
>>> {'color': 'red'}

节点与边的其他操作

当添加新的节点、边时,networkx会忽略任何已经存在的节点、边。

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()

G.add_edges_from([(1, 2), (1, 3)])
G.add_node(1)
G.add_edge(1, 2)
G.add_node("spam")        # 添加节点"spam"
G.add_nodes_from("spam")  # 添加四个节点: 's', 'p', 'a', 'm'
G.add_edge(3, 'm')

nx.draw(G , with_labels=True, font_weight='bold') #显示标签,字体加粗
plt.show()

可视化结果python networkx 复杂网络分析应用_第1张图片

同时也可以输出图中节点和边的数量等信息。

>>> G.number_of_nodes()
8
>>> G.number_of_edges()
3
>>> list(G.nodes)
[1, 2, 3, 'spam', 's', 'p', 'a', 'm']
>>> list(G.edges)
[(1, 2), (1, 3), (3, 'm')]
>>> list(G.adj[1])  # 或 list(G.neighbors(1)) , 输出节点 1 的关联节点
[2, 3]
>>> G.degree[1]  # 无向图中节点 1 的度,也就是该节点关联节点的数量,也可以理解成连接边数量
2

在图中删除节点与连边

>>> G.remove_node(2)
>>> G.remove_nodes_from("spam")
>>> G.remove_edge(1, 3)
>>>> list(G.nodes)
[1, 3, 'spam']

图的遍历操作

遍历操作是特别重要的,G.adjacency()和G.adj.items()可以对图快速遍历。
不过需要注意的是,对于无向图而言,迭代会看到每条边两次。

>>> FG = nx.Graph()
>>> FG.add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
>>> for n, nbrs in FG.adj.items():
...    for nbr, eattr in nbrs.items():
...        wt = eattr['weight']
...        if wt < 0.5: print('(%d, %d, %.3f)' % (n, nbr, wt))
(1, 2, 0.125)
(2, 1, 0.125)
(3, 4, 0.375)
(4, 3, 0.375)

通过边线属性可以方便地访问符合权重小于0.5的边。

>>> for (u, v, wt) in FG.edges.data('weight'):
...     if wt < 0.5: print('(%d, %d, %.3f)' % (u, v, wt))
(1, 2, 0.125)
(3, 4, 0.375)

有向图与度

有向图就需要指定权重,并且节点会有出度值以及入度值。

import networkx as nx
import matplotlib.pyplot as plt

DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])

print(DG.in_degree(1, weight='weight')) #节点1的入度值
print(DG.out_degree(1, weight='weight')) #节点1的出度值
print(DG.degree(1, weight='weight')) #节点1的度
>>> 0.75
>>> 0.5
>>> 1.25

其他生成图的方式

除了按节点构建图或按边构建图外,还可以通过其他方法生成图。
例如生成一个神秘的阵法。

import networkx as nx
import matplotlib.pyplot as plt

G = nx.dodecahedral_graph() #十二面体?
options = {
    'node_color': 'black',
    'node_size': 100,
    'width': 3,
}

shells = [[2, 3, 4, 5, 6], [8, 1, 0, 19, 18, 17, 16, 15, 14, 7], [9, 10, 11, 12, 13]]
nx.draw_shell(G, nlist=shells , **options)
plt.show()

python networkx 复杂网络分析应用_第2张图片

都是一些骚操作,在此不做展开。

感兴趣请访问https://networkx.github.io/documentation/stable/tutorial.html#graph-generators-and-graph-operations

networkx简单应用

以Wiki vote投票网络学习复杂网络基本名词以及networkx包对复杂网络进行基本操作,并通过随机ER图、SW小世界图和真实的合作网络数据集为例,学习网络的基本分析方法。

数据来源 Wiki投票数据

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()

#读取数据
with open('Wiki-Vote.txt') as f:
    for line in f:
        if len(line.split()) > 2: #txt文件中前面四行是注释信息
            continue              #该判断语句作用是过滤掉前四行

        data_line = line.split()
        G.add_edge(data_line[0], data_line[1])

print('网络中的节点数量:%d'%nx.number_of_nodes(G))

#有没有自己投票给自己的
print('网络有自环的节点数量:%d'%nx.number_of_selfloops(G)) 

#既然没有自环节点,那有向边数量就是所有边的数量
print('网络中有向边数量:%d'%G.number_of_edges())

#有多少对节点互相投票
count = 0
for x in G.edges:
    if (x[1],x[0]) in G.edges:
        count += 1

print('网络中互惠边数量:%d'%(count//2))

#计算入度和出度为 0 的节点
count = 0
for x in G.in_degree():
    if x[1] != 0:
        count += 1
print('网络入度为 0 的节点:%d'%(count))

count = 0
for x in G.out_degree():
    if x[1] != 0:
        count += 1
print('网络出度为 0 的节点:%d'%(count))

#计算入度和出度大于 10 的节点
count = 0
for x in G.in_degree():
    if x[1] < 10:
        count += 1
print('网络入度小于 10 的节点:%d'%(count))

count = 0
for x in G.out_degree():
    if x[1] > 10:
        count += 1
print('网络出度大于 10 的节点:%d'%(count))

输出

网络中的节点数量:7115
网络有自环的节点数量:0
网络中有向边数量:103689
网络中互惠边数量:2927
网络入度为 0 的节点:2381
网络出度为 0 的节点:6110
网络入度小于 10 的节点:5165
网络出度大于 10 的节点:1612

此为本人两年前复杂网络课程作业,本人并没有仔细关注有些计算是否有对应的方法,因此一些计算采用了迭代的方式算出结果,欢迎指正。

networkx进阶应用

有向随机图

通过调用以下方法实现

gnm_random_graph(n, k ,seed , directed=True])
返回随机图
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np

#生成n=5242个节点以及m=14484条边的有向随机图。
n = 5242
m = 14484
G1 = nx.gnm_random_graph (n,m, seed = 7 ,directed = True)

nx.draw(G1,node_size=70) 
plt.show()

Watts–Strogatz小世界图

通过调用以下方法实现

watts_strogatz_graph(n, k, p[, seed])
返回Watts–Strogatz小世界图

通过nx.watts_strogatz_graph(5242, 4, p=0, seed = 7)方法生成一个节点为5242的有向图,每个节点与相邻最近的4个节点相连,与其他节点相连的概率为0,随机种子为7,通过pos布局设置为环状。

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
n = 5242
k = 4

G = nx.watts_strogatz_graph(n, k, p=0, seed = 7)
pos = nx.circular_layout(G,scale = 1,center = None,dim = 2 )

print("sw小世界边数为:" , nx.number_of_edges(G))

Girvan-Newman算法社区检测算法

来源 https://github.com/kjahan/community

算法原理省略,社区检测算法可以简单理解为聚类。

python cmty.py graph.txt

python networkx 复杂网络分析应用_第3张图片

Max modularity (Q): 0.0183279215837773
Graph communities: [{0}, {1, 65, 66, 68, 45, 17, 30, 54, 22, 56, 57, 26, 24, 31}, {14}, {9, 11, 21, 25, 28, 29, 32, 37, 41, 43, 44, 51, 53, 55, 58, 59, 61, 63, 70, 72}, {48, 50}, {52}, {2}, {3}, {34, 4, 5}, {19, 7}, {16}, {18}, {20}, {27}, {35}, {39}, {42}, {47}, {49}, {62}, {67}, {69}, {71}, {73}, {6}, {12}, {13}, {15}, {33}, {38}, {40}, {60}, {64}, {8}, {10}, {23}, {36}, {46}, {74}]

友情提示:仔细阅读官方文档,提高编程能力,不行全问别人,除非给买好吃的。

你可能感兴趣的:(python,可视化)