Numpy 将Numpy中的邻接矩阵转换为igraph.Graph
阅读更多:Numpy 教程
背景
在处理图数据时,通常需要处理邻接矩阵(Adjacency Matrix)的表示方式,比如马尔可夫链、社交网络、生物网络等等。邻接矩阵是描述一个图形的二维矩阵,其中每个位置表示一个点对(点对的编号代表图中的点的编号),1表示两个点之间有连边,0表示两个点之间没有连边。当然,还有把连边权重直接存储在矩阵对应位置表示边权的方法,但本文主要介绍的是不带边权的邻接矩阵。
numpy和pandas是什么?
NumPy是一个用于Python编程语言的开源数学库,用于处理多维数组和矩阵,它能够支持高端数学和操作数组的较低级别的操作;Pandas是一个开源的用于数据分析的Python库,它使用DataFrame对象处理数据。在本文中,我们将使用NumPy和Pandas以及igraph库的组合来解决邻接矩阵和图形之间的转换。
Numpy中的邻接矩阵表示
让我们先在numpy中创建一个简单的邻接矩阵:
import numpy as np
adj_matrix = np.array([
[0, 1, 0],
[1, 0, 1],
[0, 1, 0]
])
这个邻接矩阵描述了一个简单的3个节点的图,其中每个节点之间只有一条边。
将Numpy中的邻接矩阵转换为igraph.Graph
在我们可以跑出网络分析算法之前,我们需要将邻接矩阵转换为适合igraph库的格式。幸运的是,邻接矩阵可以直接转换为igraph的Graph对象。以下是如何使用igraph.Graph从该邻接矩阵创建图形的示例:
import igraph
g = igraph.Graph.Adjacency(adj_matrix.tolist())
print(g)
输出如下:
IGRAPH U--- 3 2 --
+ edges:
0--1 1--2
这是一个无向图,包含3个节点和2条边。
Pandas中的邻接矩阵表示
Pandas DataFrame 继承了Python List 数据的一些特性,使它成为Python下一个非常流行的数据处理工具。
现在,我们将创建一个Pandas DataFrame 来表示一个带权图。示例中的邻接矩阵代表了4个节点之间的8条带权边:
import pandas as pd
edge_list = [
(1, 2, 1),
(1, 3, 2),
(2, 3, 3),
(2, 4, 4),
(3, 4, 5),
(1, 4, 6),
(2, 2, 7),
(3, 3, 8)
]
df = pd.DataFrame(edge_list, columns=['source', 'target', 'weight'])
adj_matrix = pd.pivot_table(df, values='weight', index=['source'], columns=['target'], fill_value=0)
adj_matrix = adj_matrix.values
将Pandas中的邻接矩阵转换为igraph.Graph
我们可以像上面的例子一样,使用igraph.Graph.Adjacency()函数来实现转换:
g = igraph.Graph.Adjacency(adj_matrix.tolist())
print(g)
但是值得注意的是此转换会导致权重信息被删除,igraph将仅处理连接信息。我们可以使用以下代码来保留权重:
, weights=adj_matrix.tolist()
那么,如何在将Pandas DataFrame转换为邻接矩阵后,重新将权重信息导入igraph中呢?这可以通过以下代码实现:
g.es['weight'] = df['weight'].tolist()
这里我们使用了igraph库的es
属性来访问图的边,然后通过weight
关键字将权重信息重新导入每条边中。
总结
通过本文,我们介绍了如何使用numpy和pandas来表示和操作邻接矩阵,以及如何使用igraph库将邻接矩阵转换为图形,以及如何保留和重新导入权重信息。这是图形数据分析中的基本部分,几乎所有的图形分析问题都需要用到这些工具。