1、基础知识

1.1、介绍

networkx在2002年5月产生,是一个用Python语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便的进行复杂网络数据分析、仿真建模等工作。

networkx支持创建简单无向图、有向图和多重图;内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富,简单易用。

1.2、作用

利用networkx可以以标准化和非标准化的数据格式存储网络、生成多种随机网络和经典网络、分析网络结构、建立网络模型、设计新的网络算法、进行网络绘制等。

1.3、Graph

1.3.1、Graph的定义

Graph是用点和线来刻画离散事物集合中的每对事物间以某种方式相联系的数学模型。

网络作为图的一个重要领域,包含的概念与定义更多,如有向图网络(Directed Graphs and Networks)、无向图网络(Undirected)等概念。

Graph在现实世界中随处可见,如交通运输图、旅游图、流程图等。此处我们只考虑由点和线所组成的图。

利用图可以描述现实生活中的许多事物,如用点可以表示交叉口,点之间的连线表示路径,这样就可以轻而易举的描绘出一个交通运输网络。

1.3.2、Graph的结构

根据Graph的定义,一个Graph包含一个节点集合和一个边集。

在NetworkX中,一个节点可以是任意hash对象(除了None对象),一条边也可以关联任意的对象,像一个文本字符串,一幅图像,一个XML对象,甚至是另一个图或任意定制的节点对象。

注意:Python中的None对象是不可以作为节点的类型的。

节点与边能够存储任意类型字典的属性和任意其他丰富类型的数据。

1.3.3、Graph分类

  • Graph:指无向图(undirected Graph),即忽略了两节点间边的方向。
  • DiGraph:指有向图(directed Graph),即考虑了边的有向性。
  • MultiGraph:指多重无向图,即两个结点之间的边数多于一条,又允许顶点通过同一条边和自己关联。
  • MultiDiGraph:多重图的有向版本。
G = nx.Graph() # 创建无向图

G = nx.DiGraph() # 创建有向图

G = nx.MultiGraph() # 创建多重无向图

G = nx.MultiDigraph() # 创建多重有向图

G.clear() #清空图

2、基本操作

2.1、无向图

  • 节点 

————如果添加的节点和边是已经存在的,是不会报错的,NetworkX会自动忽略掉已经存在的边和节点的添加。

#添加节点
import networkx as nx
import matplotlib.pyplot as plt G = nx.Graph() #建立一个空的无向图G
G.add_node('a') #添加一个节点1
G.add_nodes_from(['b','c','d','e']) #加点集合
G.add_cycle(['f','g','h','j']) #加环
H = nx.path_graph(10) #返回由10个节点挨个连接的无向图,所以有9条边
G.add_nodes_from(H) #创建一个子图H加入G
G.add_node(H) #直接将图作为节点 nx.draw(G, with_labels=True)
plt.show()

#访问节点

print('图中所有的节点', G.nodes())

print('图中节点的个数', G.number_of_nodes())

#删除节点

G.remove_node(1)    #删除指定节点
G.remove_nodes_from(['b','c','d','e']) #删除集合中的节点 nx.draw(G, with_labels=True) plt.show()

#添加边

F = nx.Graph() # 创建无向图
F.add_edge(11,12) #一次添加一条边 #等价于
e=(13,14) #e是一个元组
F.add_edge(*e) #这是python中解包裹的过程 F.add_edges_from([(1,2),(1,3)]) #通过添加list来添加多条边 #通过添加任何ebunch来添加边
F.add_edges_from(H.edges()) #不能写作F.add_edges_from(H) nx.draw(F, with_labels=True)
plt.show()

#访问边

print('图中所有的边', F.edges())

print('图中边的个数', F.number_of_edges()) 

#快速遍历每一条边,可以使用邻接迭代器实现,对于无向图,每一条边相当于两条有向边
FG = nx.Graph()
FG.add_weighted_edges_from([(1,2,0.125), (1,3,0.75), (2,4,1.2), (3,4,0.275)])
for n, nbrs in FG.adjacency():
for nbr, eattr in nbrs.items():
data = eattr['weight']
print('(%d, %d, %0.3f)' % (n,nbr,data)) print('***********************************') #筛选weight小于0.5的边:
FG = nx.Graph()
FG.add_weighted_edges_from([(1,2,0.125), (1,3,0.75), (2,4,1.2), (3,4,0.275)])
for n, nbrs in FG.adjacency():
for nbr, eattr in nbrs.items():
data = eattr['weight']
if data < 0.5:
print('(%d, %d, %0.3f)' % (n,nbr,data))
print('***********************************') #一种方便的访问所有边的方法:
for u,v,d in FG.edges(data = 'weight'):
print((u,v,d))

#删除边

F.remove_edge(1,2)
F.remove_edges_from([(11,12), (13,14)]) nx.draw(F, with_labels=True) plt.show()

  • 属性

属性诸如weight,labels,colors,或者任何对象,你都可以附加到图、节点或边上。

对于每一个图、节点和边都可以在关联的属性字典中保存一个(多个)键-值对。

默认情况下这些是一个空的字典,但是我们可以增加或者是改变这些属性。

#图的属性

import networkx as nx
import matplotlib.pyplot as plt G = nx.Graph(day='Monday') #可以在创建图时分配图的属性
print(G.graph) G.graph['day'] = 'Friday' #也可以修改已有的属性
print(G.graph) G.graph['name'] = 'time' #可以随时添加新的属性到图中
print(G.graph)

#节点的属性

G = nx.Graph(day='Monday')
G.add_node(1, index='1th') #在添加节点时分配节点属性
print(G.node(data=True)) G.node[1]['index'] = '0th' #通过G.node[][]来添加或修改属性
print(G.node(data=True)) G.add_nodes_from([2,3], index='2/3th') #从集合中添加节点时分配属性
print(G.nodes(data=True)) print(G.node(data=True))

#边的属性

G = nx.Graph(day='manday')
G.add_edge(1,2,weight=10) #在添加边时分配属性
print(G.edges(data=True)) G.add_edges_from([(1,3), (4,5)], len=22) #从集合中添加边时分配属性
print(G.edges(data='len')) G.add_edges_from([(3,4,{'hight':10}),(1,4,{'high':'unknow'})])
print(G.edges(data=True)) G[1][2]['weight'] = 100000 #通过G[][][]来添加或修改属性
print(G.edges(data=True))

注意

注意什么时候使用‘=’,什么时候使用‘:’;什么时候有引号什么时候没有引号。

特殊属性weight应该是一个数值型的,并且在算法需要使用weight时保存该数值。

2.2、其他图

有向图和多重图的基本操作与无向图一致。

无向图与有向图之间可以相互转换,转化方法如下:

#有向图转化成无向图

H=DG.to_undirected()
#或者
H=nx.Graph(DG) #无向图转化成有向图 F = H.to_directed()
#或者
F = nx.DiGraph(H)

3、Functions

degree(G[, nbunch, weight]):返回单个节点或nbunch节点的度数视图。

degree_histogram(G):返回每个度值的频率列表。

density(G):返回图的密度。

info(G[, n]):打印图G或节点n的简短信息摘要。

create_empty_copy(G[, with_data]):返回图G删除所有的边的拷贝。

is_directed(G):如果图是有向的,返回true。

add_star(G_to_add_to, nodes_for_star, **attr):在图形G_to_add_to上添加一个星形。

add_path(G_to_add_to, nodes_for_path, **attr):在图G_to_add_to中添加一条路径。

add_cycle(G_to_add_to, nodes_for_cycle, **attr):向图形G_to_add_to添加一个循环。

  • 节点

nodes(G):在图节点上返回一个迭代器。

number_of_nodes(G):返回图中节点的数量。

all_neighbors(graph, node):返回图中节点的所有邻居。

non_neighbors(graph, node):返回图中没有邻居的节点。

common_neighbors(G, u, v):返回图中两个节点的公共邻居。

edges(G[, nbunch]):返回与nbunch中的节点相关的边的视图。

number_of_edges(G):返回图中边的数目。

non_edges(graph):返回图中不存在的边。

  • 实例:在networkx中列出特定的节点或边缘

import networkx as nx
import matplotlib.pyplot as plt
G = nx.DiGraph()
G.add_edges_from([('n', 'n1'), ('n', 'n2'), ('n', 'n3')])
G.add_edges_from([('n4', 'n41'), ('n1', 'n11'), ('n1', 'n12'), ('n1', 'n13')])
G.add_edges_from([('n2', 'n21'), ('n2', 'n22')])
G.add_edges_from([('n13', 'n131'), ('n22', 'n221')])
G.add_edges_from([('n131', 'n221'), ('n221', 'n131')])
G.add_node('n5')
nx.draw(G, with_labels=True)
plt.show()

1、使用out_degree函数查找所有带有子项的节点:

>>> [k for k,v in G.out_degree().iteritems() if v > 0]
['n13', 'n', 'n131', 'n1', 'n22', 'n2', 'n221', 'n4']

2、所有没有孩子的节点:

>>> [k for k,v in G.out_degree().iteritems() if v == 0]
['n12', 'n11', 'n3', 'n41', 'n21', 'n5']

3、所有孤儿节点,即度数为0的节点:

>>> [k for k,v in G.degree().iteritems() if v == 0]
['n5'] 

4、超过2个孩子的节点:

>>> [k for k,v in G.out_degree().iteritems() if v > 2]
['n', 'n1']

4、经典图论算法

  • 最短路径

函数调用: 

dijkstra_path(G, source, target, weight='weight')             ————求最短路径

dijkstra_path_length(G, source, target, weight='weight')      ————求最短距离

示例

import networkx as nx
import pylab
import numpy as np
#自定义网络
row=np.array([0,0,0,1,2,3,6])
col=np.array([1,2,3,4,5,6,7])
value=np.array([1,2,1,8,1,3,5]) print('生成一个空的有向图')
G=nx.DiGraph()
print('为这个网络添加节点...')
for i in range(0,np.size(col)+1):
G.add_node(i)
print('在网络中添加带权中的边...')
for i in range(np.size(row)):
G.add_weighted_edges_from([(row[i],col[i],value[i])]) print('给网路设置布局...')
pos=nx.shell_layout(G)
print('画出网络图像:')
nx.draw(G,pos,with_labels=True, node_color='white', edge_color='red', node_size=400, alpha=0.5 )
pylab.title('Self_Define Net',fontsize=15)
pylab.show() '''
Shortest Path with dijkstra_path
'''
print('dijkstra方法寻找最短路径:')
path=nx.dijkstra_path(G, source=0, target=7)
print('节点0到7的路径:', path)
print('dijkstra方法寻找最短距离:')
distance=nx.dijkstra_path_length(G, source=0, target=7)
print('节点0到7的距离为:', distance) 

  • 最小生成树

定义:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。

示例:

def prim(G, s):
dist = {} # dist记录到节点的最小距离
parent = {} # parent记录最小生成树的双亲表
Q = list(G.nodes()) # Q包含所有未被生成树覆盖的节点
MAXDIST = 9999.99 # MAXDIST表示正无穷,即两节点不邻接 # 初始化数据
# 所有节点的最小距离设为MAXDIST,父节点设为None
for v in G.nodes():
dist[v] = MAXDIST
parent[v] = None
# 到开始节点s的距离设为0
dist[s] = 0 # 不断从Q中取出“最近”的节点加入最小生成树
# 当Q为空时停止循环,算法结束
while Q:
# 取出“最近”的节点u,把u加入最小生成树
u = Q[0]
for v in Q:
if (dist[v] < dist[u]):
u = v
Q.remove(u) # 更新u的邻接节点的最小距离
for v in G.adj[u]:
if (v in Q) and (G[u][v]['weight'] < dist[v]):
parent[v] = u
dist[v] = G[u][v]['weight']
# 算法结束,以双亲表的形式返回最小生成树
return parent
import matplotlib.pyplot as plt
import networkx as nx g_data = [(1, 2, 1.3), (1, 3, 2.1), (1, 4, 0.9), (1, 5, 0.7), (1, 6, 1.8), (1, 7, 2.0), (1, 8, 1.8), (2, 3, 0.9), (2, 4, 1.8), (2, 5, 1.2), (2, 6, 2.8), (2, 7, 2.3), (2, 8, 1.1), (3, 4, 2.6), (3, 5, 1.7), (3, 6, 2.5), (3, 7, 1.9), (3, 8, 1.0), (4, 5, 0.7), (4, 6, 1.6), (4, 7, 1.5), (4, 8, 0.9), (5, 6, 0.9), (5, 7, 1.1), (5, 8, 0.8), (6, 7, 0.6), (6, 8, 1.0), (7, 8, 0.5)] def draw(g):
pos = nx.spring_layout(g)
nx.draw(g, pos, \
arrows=True, \
with_labels=True, \
nodelist=g.nodes(), \
style='dashed', \
edge_color='b', \
width=2, \
node_color='y', \
alpha=0.5)
plt.show() g = nx.Graph()

tree = prim(g, 1)

mtg = nx.Graph()
mtg.add_edges_from(tree.items())
mtg.remove_node(None) draw(mtg)

  • 最大联通子图及联通子图规模排序

import matplotlib.pyplot as plt
import networkx as nx
G=nx.path_graph(4)
G.add_path([10,11,12])
nx.draw(G,with_labels=True,label_size=1000,node_size=1000,font_size=20)
plt.show()
#[print(len(c)) for c in sorted(nx.connected_components(G),key=len,reverse=True)]
for c in sorted(nx.connected_components(G),key=len,reverse=True):
print(c) #看看返回来的是什么?结果是{0,1,2,3}
print(type(c)) #类型是set
print(len(c)) #长度分别是4和3(因为reverse=True,降序排列) largest_components=max(nx.connected_components(G),key=len) # 高效找出最大的联通成分,其实就是sorted里面的No.1
print(largest_components) #找出最大联通成分,返回是一个set{0,1,2,3}
print(len(largest_components)) #

{0, 1, 2, 3}
<class 'set'>
4
{10, 11, 12}
<class 'set'>
3
{0, 1, 2, 3}
4

参考资料:

http://yoghurt-lee.online/2017/03/30/graph-visible/

http://blog.sciencenet.cn/home.php?mod=space&uid=404069&do=blog&id=337442

http://www.cnblogs.com/kaituorensheng/p/5423131.html#_label3

http://baiyejianxin.iteye.com/blog/1764048

https://zhuanlan.zhihu.com/p/33616557

https://blog.csdn.net/qq_31192383/article/details/53748129

https://blog.csdn.net/newbieMath/article/details/73800374

http://osask.cn/front/ask/view/565531

 

networkx整理的更多相关文章

  1. [Python] networkx入门 转

    networkx是python的一个第三方包,可以方便地调用各种图算法的计算. 通过调用python画图包matplotlib能实现图的可视化. 1.安装 正好整理一下python第三方包的安装方法. ...

  2. 『Networkx』常用方法

    这是一个用于分析'图'结构的包,由于我只是用到了浅显的可视化功能,所以这个介绍会对其使用浅尝辄止. 解决matplotlib中文字体缺失问题, from pylab import mpl mpl.rc ...

  3. Python框架、库和软件资源大全(整理篇)

    有少量修改,请访问原始链接.PythonWIn的exe安装包;http://www.lfd.uci.edu/~gohlke/pythonlibs/ 原文链接:codecloud.net/python- ...

  4. 这几天加班熬夜把所有Python库整理了一遍,非常全面!

    库名称简介 Chardet 字符编码探测器,可以自动检测文本.网页.xml的编码.colorama 主要用来给文本添加各种颜色,并且非常简单易用.Prettytable 主要用于在终端或浏览器端构建格 ...

  5. 花了三个月终于把所有的 Python 库全部整理了!可以说很全面了

    库名称简介 Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主要用于在终端或浏览器端构建格式 ...

  6. NetworkX系列教程(1)-创建graph

    小书匠Graph图论 研究中经常涉及到图论的相关知识,而且常常面对某些术语时,根本不知道在说什么.前不久接触了NetworkX这个graph处理工具,发现这个工具已经解决绝大部分的图论问题(也许只是我 ...

  7. Python全部库整理

    库名称简介 Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主要用于在终端或浏览器端构建格式 ...

  8. Python库整理

    库名称简介 Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主要用于在终端或浏览器端构建格式 ...

  9. [转载]花了半个月,终于把Python库全部整理出来了,非常全面

    库名称简介 Chardet 字符编码探测器,可以自动检测文本.网页.xml的编码. colorama 主要用来给文本添加各种颜色,并且非常简单易用. Prettytable 主要用于在终端或浏览器端构 ...

随机推荐

  1. Python集训营45天—Day08 (文件操作)

    目录 1. 文件操作介绍 2. 文件的读写 2.1 文本文件 2.2 二进制文件 2.3 JSON文件 3. 文件的定位,重命名和删除 4. 文件夹的相关操作 1. 文件操作介绍 大家应该听说过一句话 ...

  2. Laravel Entrust 权限管理扩展包的使用笔记

    简介 Entrust 是一个简洁而灵活的基于角色进行权限管理的 Laravel 扩展包.针对 Laravel 5,官方推荐的安装版本是 5.2.x-dev.它的详细使用方法请查看 Entrust Gi ...

  3. 高清屏下canvas重置尺寸引发的问题

    我们知道,清空canvas画布内容有以下两个方法. 第一种方法是cearRect函数: context.cearRect(0,0,canvas.width,canvas.height) 第二种方法就是 ...

  4. python爬虫之基本类库

    简单梳理一下爬虫原理: 1.发送请求 通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,等待服务器响应. 2.获取响应内容 如果服务器能正常响应(正常 ...

  5. Linux学习资料网站汇总链接(持续更新ing)

    排名不分先后. 学海无涯苦作舟. 博客: 1.slmba:LINUX博客原创大牛 2.edsionte's TechBlog:Linuxer (他的友情链接中还有一堆Linuxer,被公司屏蔽进不去. ...

  6. docker的使用 一容器命令

    Docker容器命令 前提 执行容器的前提是有镜像 . #创建并启动容器 docker run [options] images [command][args] // option 的说明 --nam ...

  7. 代码审计-phpcms9.6.2任意文件下载漏洞

    漏洞文件: phpcms\modules\content\down.php 1.在download函数中对文件的校验部分 首先 if(preg_match('/(php|phtml|php3|php4 ...

  8. Cobalt Strike之CHM、LNK、HTA钓鱼

    CHM钓鱼 CHM介绍 CHM(Compiled Help Manual)即“已编译的帮助文件”.它是微软新一代的帮助文件格式,利用HTML作源文,把帮助内容以类似数据库的形式编译储存.利用CHM钓鱼 ...

  9. 爬虫3:html页面+webdriver模块+demo

    保密性好的网站,不能使用request请求页面信息,这样可以使用webdriver模块先开启一个浏览器,然后爬去信息,甚至还可以click等操作对页面操作,再爬取. demo 一般流程: 1)包含se ...

  10. 机器学习:数据清洗及工具OpenRefine

    数据分析中,首先要进行数据清洗,才可以继续训练模型,预测等操作. 首先介绍一下什么是数据清洗(定义来自 百度百科,有删减) 数据清洗从名字上也看的出就是把“脏”的“洗掉”,指发现并纠正数据文件中可识别 ...