开源内容:https://github.com/TommyZihao/zihao_course/tree/main/CS224W
子豪兄B 站视频:https://space.bilibili.com/1900783/channel/collectiondetail?sid=915098
斯坦福官方课程主页:https://web.stanford.edu/class/cs224w
NetworkX主页:https://networkx.org
文章目录
- NetworkX创建图
- 内置图
- 连接表和邻接表创建图
- NetworkX创建节点
- NetworkX创建连接
- 总结
NetworkX创建图
内置图
通过NetworkX自带的函数和API,创建内置的样例图,包括各种有向图、无向图、栅格图、随机图、社交网络,这里举几个常见的例子,更多例子见networkx创建图
经典图结构
plt.figure(figsize=(10,8), dpi=90)
#全连接无向图
plt.subplot(241)
G = nx.complete_graph(7)
nx.draw(G)
#全连接有向图
plt.subplot(242)
G = nx.complete_graph(7, nx.DiGraph())
nx.draw(G)
#环状图
plt.subplot(243)
G = nx.cycle_graph(5)
nx.draw(G)
#梯状图
plt.subplot(244)
G = nx.ladder_graph(5)
nx.draw(G)
#线性串珠图
plt.subplot(245)
G = nx.path_graph(15)
nx.draw(G)
#星状图
plt.subplot(246)
G = nx.star_graph(7)
nx.draw(G)
#轮辐图
plt.subplot(247)
G = nx.wheel_graph(8)
nx.draw(G)
#二项树
plt.subplot(248)
G = nx.binomial_tree(5)
nx.draw(G)
栅格图
plt.figure(figsize=(10,8), dpi=90)
# 二维矩形网格图
plt.subplot(231)
G = nx.grid_2d_graph(3,5)
nx.draw(G)
# 多维矩形网格图
plt.subplot(232)
G = nx.grid_graph(dim=(2, 3, 4))
nx.draw(G)
# 二维三角形网格图
plt.subplot(233)
G = nx.triangular_lattice_graph(2,5)
nx.draw(G)
# 二维六边形蜂窝图
plt.subplot(234)
G = nx.hexagonal_lattice_graph(2,3)
nx.draw(G)
# n维超立方体图
plt.subplot(235)
G = nx.hypercube_graph(4)
nx.draw(G)
NetworkX内置图
plt.figure(figsize=(10,8), dpi=90)
plt.subplot(241)
G = nx.diamond_graph()
nx.draw(G)
plt.subplot(242)
G = nx.bull_graph()
nx.draw(G)
plt.subplot(243)
G = nx.frucht_graph()
nx.draw(G)
plt.subplot(244)
G = nx.house_graph()
nx.draw(G)
plt.subplot(245)
G = nx.house_x_graph()
nx.draw(G)
plt.subplot(246)
G = nx.petersen_graph()
nx.draw(G)
plt.subplot(247)
G = nx.krackhardt_kite_graph()
nx.draw(G)
随机图
G = nx.erdos_renyi_graph(10, 0.5)
nx.draw(G)
社交网络
空手道俱乐部的人物关系
G = nx.karate_club_graph()
nx.draw(G, with_labels=True)
我们可以查看节点对应的俱乐部
print(G.nodes[5]["club"])
print(G.nodes[9]["club"])
雨果《悲惨世界》人物关系
G = nx.les_miserables_graph()
plt.figure(figsize=(12,10))
pos = nx.spring_layout(G, seed=10)
nx.draw(G, pos, with_labels=True)
社群聚类图
G = nx.caveman_graph(4, 3)
nx.draw(G, with_labels=True)
树
tree = nx.random_tree(n=10, seed=0)
print(nx.forest_str(tree, sources=[0]))
连接表和邻接表创建图
在NetworkX中,通过连接表和邻接表创建图。
首先配置所需要的环境
import networkx as nx
import numpy as np
import random # 随机数
import pandas as pd
# 数据可视化
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
# windows操作系统
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
导入三元组连接表
数据来源:OpenKG-四大名著人物关系知识图谱和OWL本体:http://www.openkg.cn/dataset/ch4masterpieces
# 导入 csv 文件定义的三元组连接表,构建有向图
df = pd.read_csv('triples.csv')
df
通过连接表Edge List创建图
G = nx.DiGraph()
edges = [edge for edge in zip(df['head'], df['tail'])]
G.add_edges_from(edges)
G.edges('刘备')
OutEdgeDataView([(‘刘备’, ‘诸葛亮’), (‘刘备’, ‘马超’), (‘刘备’, ‘徐庶’), (‘刘备’, ‘姜维’), (‘刘备’, ‘糜芳’), (‘刘备’, ‘糜竺’), (‘刘备’, ‘魏延’), (‘刘备’, ‘赵云’), (‘刘备’, ‘黄忠’), (‘刘备’, ‘庞统’), (‘刘备’, ‘法正’), (‘刘备’, ‘蒋琬’), (‘刘备’, ‘马良’), (‘刘备’, ‘孟获’), (‘刘备’, ‘沙摩柯’)])
可视化
# 节点排版布局-默认弹簧布局
pos = nx.spring_layout(G, seed=123)
plt.figure(figsize=(15,12))
nx.draw(G, pos=pos, with_labels=True)
查看全图参数
print(G)
print(len(G))
print(G.size())
print(G.nodes)
DiGraph with 123 nodes and 144 edges
123
144
[‘关羽’, ‘刘备’, ‘张飞’, ‘张苞’, ‘关兴’, ‘关平’, ‘卢植’, ‘公孙瓒’, ‘甘氏’, ‘刘禅’, ‘诸葛瞻’, ‘诸葛亮’, ‘姜维’, ‘黄月英’, ‘黄承彦’, ‘诸葛瑾’, ‘公孙越’, ‘马超’, ‘马腾’, ‘韩遂’, ‘徐庶’, ‘曹操’, ‘刘胜’, ‘刘启’, ‘刘辩’, ‘孙权’, ‘孙尚香’, ‘糜氏’, ‘糜芳’, ‘糜竺’, ‘魏延’, ‘赵云’, ‘黄忠’, ‘庞统’, ‘法正’, ‘蒋琬’, ‘马良’, ‘孟获’, ‘沙摩柯’, ‘庞德公’, ‘马谡’, ‘祝融’, ‘孙韶’, ‘孙策’, ‘孙氏’, ‘陆逊’, ‘刘协’, ‘董卓’, ‘王允’, ‘貂蝉’, ‘吕布’, ‘丁原’, ‘高顺’, ‘陈宫’, ‘张辽’, ‘刘表’, ‘蔡氏’, ‘蔡瑁’, ‘蒯越’, ‘黄祖’, ‘文聘’, ‘张宝’, ‘张角’, ‘张梁’, ‘袁绍’, ‘袁术’, ‘袁谭’, ‘袁熙’, ‘袁尚’, ‘吴国太’, ‘孙坚’, ‘大乔’, ‘小乔’, ‘周瑜’, ‘丁奉’, ‘徐盛’, ‘鲁肃’, ‘张昭’, ‘蒋钦’, ‘太史慈’, ‘周泰’, ‘凌统’, ‘吕蒙’, ‘甘宁’, ‘黄盖’, ‘韩当’, ‘程普’, ‘曹嵩’, ‘吕伯奢’, ‘邹氏’, ‘张绣’, ‘清河公主’, ‘夏侯楙’, ‘夏侯渊’, ‘夏侯淳’, ‘曹真’, ‘曹爽’, ‘郭嘉’, ‘徐晃’, ‘乐进’, ‘张郃’, ‘许褚’, ‘典韦’, ‘荀彧’, ‘荀攸’, ‘贾诩’, ‘司马懿’, ‘程昱’, ‘于禁’, ‘邓艾’, ‘钟会’, ‘庞德’, ‘司马师’, ‘司马昭’, ‘司马炎’, ‘曹仁’, ‘曹纯’, ‘曹昂’, ‘刘氏’, ‘超昂’, ‘卞氏’, ‘曹丕’, ‘曹植’]
保存并载入邻接表 Adjacency List
# 将邻接表导出为本地文件 grid.edgelist
nx.write_edgelist(G, path="grid.edgelist", delimiter=":")
# 从本地文件 grid.edgelist 读取邻接表
H = nx.read_edgelist(path="grid.edgelist", delimiter=":")
# 可视化
plt.figure(figsize=(15,14))
pos = nx.spring_layout(H, iterations=3, seed=5)
nx.draw(H, pos, with_labels=True)
plt.show()
NetworkX创建节点
在NetworkX中创建单个节点、创建多个节点、图本身作为节点。
节点可以为任意可哈希的对象,比如字符串、图像、XML对象,甚至另一个Graph、自定义的节点对象。
通过这种方式,你可以根据你的应用,自由灵活地构建:图为节点、文件为节点、函数为节点,等灵活的图形式。
# 图数据挖掘
import networkx as nx
# 数据可视化
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
创建无节点、无连接的空图
G = nx.Graph()
G.nodes
NodeView(())
添加单个节点
G.add_node('刘备')
G.add_node('Tommy')
G.add_node(1)
G.nodes
NodeView((‘刘备’, ‘Tommy’, 1))
添加多个节点
G.add_nodes_from(['诸葛亮', '曹操'])
G.add_nodes_from(range(100, 105))
G.nodes
NodeView((‘刘备’, ‘Tommy’, 1, ‘诸葛亮’, ‘曹操’, 100, 101, 102, 103, 104))
添加带属性特征的节点
G.add_nodes_from([
('关羽',{'武器': '青龙偃月刀','武力值':90,'智力值':80}),
('张飞',{'武器': '丈八蛇矛','武力值':85,'智力值':75}),
('吕布',{'武器':'方天画戟','武力值':100,'智力值':70})
])
G.nodes
# 可视化
nx.draw(G)
NodeView((‘刘备’, ‘Tommy’, 1, ‘诸葛亮’, ‘曹操’, 100, 101, 102, 103, 104, ‘关羽’, ‘张飞’, ‘吕布’))
创建另一个首尾相连成串的Path Graph
H = nx.path_graph(10)
H.nodes
# 可视化
nx.draw(H)
NodeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
将H的节点添加到G中
G.add_nodes_from(H)
G.nodes
NodeView((‘刘备’, ‘Tommy’, 1, ‘诸葛亮’, ‘曹操’, 100, 101, 102, 103, 104, ‘关羽’, ‘张飞’, ‘吕布’, 0, 2, 3, 4, 5, 6, 7, 8, 9))
将H本身作为一个节点添加到G中
G.add_node(H)
G.nodes
NetworkX创建连接
在NetworkX中创建连接,设置连接的属性特征。
# 图数据挖掘
import networkx as nx
# 数据可视化
import matplotlib.pyplot as plt
%matplotlib inline
# plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
首先我们要先创建一个图
# 创建无向图
G = nx.Graph()
# 给整张图添加特征属性
G.graph['Name'] = 'HelloWorld'
# 创建有向图
H = nx.DiGraph()
接下来我们给图添加节点
# 创建0号节点,并添加特征属性
G.add_node(0, feature=5, label=0, zihao=2)
G.add_nodes_from([
(1, {'feature': 1, 'label': 1, 'zihao':3}),
(2, {'feature': 2, 'label': 2, 'zihao':4})
])
# 遍历所有节点,data=True 表示输出节点特征属性信息
for node in G.nodes(data=True):
print(node)
(0, {‘feature’: 5, ‘label’: 0, ‘zihao’: 2})
(1, {‘feature’: 1, ‘label’: 1, ‘zihao’: 3})
(2, {‘feature’: 2, ‘label’: 2, ‘zihao’: 4})
创建单个连接,设置属性特征
特征属性的名字可以随便起
G.add_edge(0, 1, weight=0.5, like=3)
创建多个连接
G.add_edges_from([
(1, 2, {'weight': 0.3, 'like':5}),
(2, 0, {'weight': 0.1, 'like':8})
])
G.edges[(0, 1)]
#可视化
nx.draw(G, with_labels = True)
{‘weight’: 0.5, ‘like’: 3}
全图连接信息
print(G.number_of_edges())
print(G.size())
print(G.edges())
print(G.edges(data=True))
# 遍历所有连接,data=True 表示输出连接特征属性信息
for edge in G.edges(data=True):
print(edge)
3
3
[(0, 1), (0, 2), (1, 2)]
[(0, 1, {‘weight’: 0.5, ‘like’: 3}), (0, 2, {‘weight’: 0.1, ‘like’: 8}), (1, 2, {‘weight’: 0.3, ‘like’: 5})]
(0, 1, {‘weight’: 0.5, ‘like’: 3})
(0, 2, {‘weight’: 0.1, ‘like’: 8})
(1, 2, {‘weight’: 0.3, ‘like’: 5})
节点的连接数(Node Degree)
# 指定节点
node_id = 1
print("节点{}的度为{}".format(node_id,G.degree[node_id]))
# 指定节点的所有相邻节点
for neighbor in G.neighbors(node_id):
print("Node {} has neighbor {}".format(node_id, neighbor))
节点1的度为2
Node 1 has neighbor 0
Node 1 has neighbor 2
总结
本篇文章主要介绍了如何通过NetworkX工具包创建图、节点和连接。
通过NetworkX自带的函数和API,创建内置的样例图,包括各种有向图、无向图、栅格图、随机图、社交网络。
在NetworkX中创建单个节点、创建多个节点、图本身作为节点。
在NetworkX中创建连接,设置连接的属性特征。