tynbl.github.io

网络基础

import networkx as nx
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib notebook

1. 创建图

1.1 添加节点

G = nx.Graph()

# 添加单个节点
G.add_node(1)

# 添加节点列表
G.add_nodes_from([2, 3])
G.nodes()
[1, 2, 3]

1.2 添加边

# 添加指定节点间的边
G.add_edge(1, 2)
# 以元组形式添加
e = (2, 3)
G.add_edge(*e)
# 添加多条边
G.add_edges_from([(1, 2), (1, 3)])
# 查看图信息
print('节点个数:', G.number_of_nodes())
print(G.nodes())

print()
print('边个数:', G.number_of_edges())
print(G.edges())
节点个数: 3
[1, 2, 3]

边个数: 3
[(1, 2), (1, 3), (2, 3)]
# 查看相邻节点
print(G.neighbors(2))
[1, 3]
# 移除边
G.remove_edge(1, 3)

print('边个数:', G.number_of_edges())
print(G.edges())
边个数: 2
[(1, 2), (2, 3)]
# 节点和边可以为任意的数据类型,通常为数字或字符
G.add_node('a')
G.add_node('bv')
G.add_edge('a', 1)
# 简单可视化
plt.figure()
nx.draw_networkx(G)
<IPython.core.display.Javascript object>

2. 其他方式创建图

2.1 邻接列表

G2 = nx.read_adjlist('G_adjlist.txt', nodetype=int)
list(G2.edges())
[(0, 1),
 (0, 2),
 (0, 3),
 (0, 5),
 (1, 3),
 (1, 6),
 (3, 4),
 (4, 5),
 (4, 7),
 (5, 8),
 (8, 9)]
plt.figure()
nx.draw_networkx(G2)
<IPython.core.display.Javascript object>

2.2 邻接矩阵

G_mat = np.array([[0, 1, 1, 1, 0, 1, 0, 0, 0, 0],
                  [1, 0, 0, 1, 0, 0, 1, 0, 0, 0],
                  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                  [1, 1, 0, 0, 1, 0, 0, 0, 0, 0],
                  [0, 0, 0, 1, 0, 1, 0, 1, 0, 0],
                  [1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                  [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
                  [0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
                 ])
G3 = nx.Graph(G_mat)
list(G3.edges())
[(0, 1),
 (0, 2),
 (0, 3),
 (0, 5),
 (1, 3),
 (1, 6),
 (3, 4),
 (4, 5),
 (4, 7),
 (5, 8),
 (8, 9)]
plt.figure()
nx.draw_networkx(G3)
<IPython.core.display.Javascript object>

2.3 边列表

G4 = nx.read_edgelist('G_edgelist.txt', data=[('Weight', int)])
list(G4.edges(data=True))
[('1', '3', {'Weight': 2}),
 ('1', '0', {'Weight': 4}),
 ('1', '6', {'Weight': 5}),
 ('3', '0', {'Weight': 2}),
 ('3', '4', {'Weight': 3}),
 ('0', '2', {'Weight': 3}),
 ('0', '5', {'Weight': 6}),
 ('9', '8', {'Weight': 1}),
 ('7', '4', {'Weight': 2}),
 ('8', '5', {'Weight': 6}),
 ('5', '4', {'Weight': 1})]
plt.figure()
nx.draw_networkx(G4)
<IPython.core.display.Javascript object>

2.4 DataFrame

G_df = pd.read_csv('G_edgelist.txt', delim_whitespace=True,
                  header=None, names=['n1', 'n2', 'weight'])
G_df
n1 n2 weight
0 0 1 4
1 0 2 3
2 0 3 2
3 0 5 6
4 1 3 2
5 1 6 5
6 3 4 3
7 4 5 1
8 4 7 2
9 5 8 6
10 8 9 1
G5 = nx.from_pandas_dataframe(G_df, 'n1', 'n2', edge_attr='weight')
list(G5.edges(data=True))
[(0, 1, {'weight': 4}),
 (0, 2, {'weight': 3}),
 (0, 3, {'weight': 2}),
 (0, 5, {'weight': 6}),
 (1, 3, {'weight': 2}),
 (1, 6, {'weight': 5}),
 (3, 4, {'weight': 3}),
 (4, 5, {'weight': 1}),
 (4, 7, {'weight': 2}),
 (5, 8, {'weight': 6}),
 (8, 9, {'weight': 1})]
plt.figure()
nx.draw_networkx(G5)
<IPython.core.display.Javascript object>

3. 访问边

G6 = nx.Graph()
G6.add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
plt.figure()
nx.draw_networkx(G6)
<IPython.core.display.Javascript object>

# 返回节点和邻居节点
for n, nbrs in G6.adjacency_iter():
    print(n, nbrs)
1 {2: {'weight': 0.125}, 3: {'weight': 0.75}}
2 {1: {'weight': 0.125}, 4: {'weight': 1.2}}
3 {1: {'weight': 0.75}, 4: {'weight': 0.375}}
4 {2: {'weight': 1.2}, 3: {'weight': 0.375}}
# 遍历边
# 找出权重小于0.5的边
for n, nbrs in G6.adjacency_iter():
    # adjacency_iter 返回节点和邻居节点
    for nbr, edge_attr in nbrs.items():
        data = edge_attr['weight']
        if data < 0.5: 
            print('({}, {}, {:.3f})'.format(n, nbr, data))
(1, 2, 0.125)
(2, 1, 0.125)
(3, 4, 0.375)
(4, 3, 0.375)

4. 为图添加属性

4.1 图属性

G7 = nx.Graph(day = "Friday")
G7.graph
{'day': 'Friday'}
G7.graph['day'] = 'Monday'
G7.graph
{'day': 'Monday'}

4.2 节点属性

G7.add_node(1, time='5pm')
G7.add_nodes_from([3], time='2pm')
G7.node
{1: {'time': '5pm'}, 3: {'time': '2pm'}}
G7.node[1]['room'] = 714
G7.nodes()
[1, 3]
# data=True 表示连属性一起输出
G7.nodes(data=True)
[(1, {'room': 714, 'time': '5pm'}), (3, {'time': '2pm'})]

4.3 边属性

G7.add_edge(1, 2, weight=4.7 )
G7.add_edges_from([(3, 4), (4, 5)], color='red')
G7.add_edges_from([(1, 2, {'color':'blue'}), (2, 3, {'weight':8})])
G7.edges(data=True)
[(1, 2, {'color': 'blue', 'weight': 4.7}),
 (2, 3, {'weight': 8}),
 (3, 4, {'color': 'red'}),
 (4, 5, {'color': 'red'})]
# 修改边属性
G7[1][2]['weight'] = 4.7

# 或者
G7.edge[1][2]['weight'] = 4
G7.edges(data=True)
[(1, 2, {'color': 'blue', 'weight': 4}),
 (2, 3, {'weight': 8}),
 (3, 4, {'color': 'red'}),
 (4, 5, {'color': 'red'})]

5. 网络类型

5.1 无向图

G8 = nx.Graph()
G8.add_edge('A', 'B')
G8.add_edge('B', 'C')

plt.figure()
nx.draw_networkx(G8)
<IPython.core.display.Javascript object>

5.2 有向图

G9 = nx.DiGraph()
G9.add_edge('B', 'A')
G9.add_edge('B', 'C')

plt.figure()
nx.draw_networkx(G9)
<IPython.core.display.Javascript object>

5.3 权重网络

G10 = nx.Graph()
G10.add_edge('A', 'B', weight=6)
G10.add_edge('B', 'C', weight=13)

G10.edges(data=True)
[('C', 'B', {'weight': 13}), ('A', 'B', {'weight': 6})]

5.4 符号网络

G11 = nx.Graph()
G11.add_edge('A', 'B', sign='+')
G11.add_edge('B', 'C', sign='-')

G11.edges(data=True)
[('C', 'B', {'sign': '-'}), ('A', 'B', {'sign': '+'})]
G12 = nx.Graph()
G12.add_edge('A', 'B', relation='friend')
G12.add_edge('B', 'C', relation='coworker')
G12.add_edge('D', 'E', relation='family')
G12.add_edge('E', 'I', relation='neighbor')

G12.edges(data=True)
[('C', 'B', {'relation': 'coworker'}),
 ('I', 'E', {'relation': 'neighbor'}),
 ('E', 'D', {'relation': 'family'}),
 ('A', 'B', {'relation': 'friend'})]

5.5 多重图

G13 = nx.MultiGraph()
G13.add_edge('A', 'B', relation='friend')
G13.add_edge('A', 'B', relation='neighbor')
G13.add_edge('G', 'F', relation='family')
G13.add_edge('G', 'F', relation='coworker')

G13.edges(data=True)
[('A', 'B', {'relation': 'friend'}),
 ('A', 'B', {'relation': 'neighbor'}),
 ('G', 'F', {'relation': 'family'}),
 ('G', 'F', {'relation': 'coworker'})]

6. 网络的属性访问

6.1 边属性的访问

G14 = nx.Graph()
G14.add_edge('A', 'B', weight=6, relation='family')
G14.add_edge('B', 'C', weight=13, relation='friend')
G14.edges() # 列出所有的边
[('C', 'B'), ('A', 'B')]
G14.edges(data=True) # 列出边,并且带属性
[('C', 'B', {'relation': 'friend', 'weight': 13}),
 ('A', 'B', {'relation': 'family', 'weight': 6})]
G14.edges(data='relation') #指定属性的输出
[('C', 'B', 'friend'), ('A', 'B', 'family')]
G14.edge['A']['B']  # 边(A, B)的属性字典
{'relation': 'family', 'weight': 6}
G14.edge['B']['C']['weight']
13
G14.edge['C']['B']['weight'] # 无向图中节点顺序无关
13
# 有向权重网络
G14 = nx.DiGraph()
G14.add_edge('A', 'B', weight=6, relation='family')
G14.add_edge('C', 'B', weight=13, relation='friend')
G14.edge['C']['B']['weight']
13
G14.edge['B']['C']['weight']  # 注意有向图的节点顺序
---------------------------------------------------------------------------

KeyError                                  Traceback (most recent call last)

<ipython-input-92-f05b6ce7b641> in <module>()
----> 1 G14.edge['B']['C']['weight']  # 注意有向图的节点顺序


KeyError: 'C'

6.2 边属性的访问

G15 = nx.Graph()
G15.add_edge('A', 'B', weight=6, relation='family')
G15.add_edge('B', 'C', weight=13, relation='friend')
# 为节点添加属性
G15.add_node('A', role='trader')
G15.add_node('B', role='trader')
G15.add_node('C', role='manager')
G15.nodes()  # 列出所有节点
['C', 'A', 'B']
G15.nodes(data=True)  # 列出所有节点带属性
[('C', {'role': 'manager'}),
 ('A', {'role': 'trader'}),
 ('B', {'role': 'trader'})]
G15.node['A']['role']  # 访问单个节点带属性
'trader'