python - 从二维单元格numpy数组中获取邻接矩阵的最佳方法
问题描述
给定一个值数组:
x = array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
我想知道是否有一种最佳方法可以轻松获得其等效邻接矩阵:
M = array([[ inf, 1., inf, 3., 4., inf, inf, inf, inf],
[ 0., inf, 2., 3., 4., 5., inf, inf, inf],
[ inf, 1., inf, inf, 4., 5., inf, inf, inf],
[ 0., 1., inf, inf, 4., inf, 6., 7., inf],
[ 0., 1., 2., 3., inf, 5., 6., 7., 8.],
[ inf, 1., 2., inf, 4., inf, inf, 7., 8.],
[ inf, inf, inf, 3., 4., inf, inf, 7., inf],
[ inf, inf, inf, 3., 4., 5., 6., inf, 8.],
[ inf, inf, inf, inf, 4., 5., inf, 7., inf]])
这个想法实际上是在networx中构建一个可以使用的对象,我希望获得一个单元格网格的邻接矩阵,以便能够在networkx中加载该矩阵,但是如果有更好的方法来实现它我是接受建议。根据文档,我已经能够找到 grid_2d_graph () 函数,该函数允许在给定原始矩阵的 n 行和 m 列的情况下确定我想要的图形的尺寸,但是我希望权重从一个节点转移到另一个节点(如果可能) ,为目标节点占用的数组的值。
编辑
尽管提出的示例是一种特殊情况(方阵和有序值),但任何矩阵都会出现问题,其维度不一定相等且值为随机值。
解决方案
我想这就是你所追求的:
def create_adj_mat(x):
y = np.ones([x.size,np.max(x)+1]) * np.inf #initialize
for I,i in enumerate(np.ravel(x)):
#get adjacent values of y and x points
d = x[max(0,I//x.shape[1]-1):min(x.shape[0],I//x.shape[1]+2),
max(0,I%x.shape[1]-1):min(x.shape[1],I%x.shape[1]+2)]
y[I,np.ravel(d)] = np.ravel(d)
np.fill_diagonal(y,np.inf) #remove i,i points
return y
它遍历输入矩阵的散列值并找到相邻值(-1 和 +2 偏移,+2 因为 python 索引)并根据这些值设置数组 y。
当你传递你的矩阵时,你会得到:
x = np.array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
y = create_adj_mat(x)
print(y)
array([[inf, 1., inf, 3., 4., inf, inf, inf, inf],
[ 0., inf, 2., 3., 4., 5., inf, inf, inf],
[inf, 1., inf, inf, 4., 5., inf, inf, inf],
[ 0., 1., inf, inf, 4., inf, 6., 7., inf],
[ 0., 1., 2., 3., inf, 5., 6., 7., 8.],
[inf, 1., 2., inf, 4., inf, inf, 7., 8.],
[inf, inf, inf, 3., 4., inf, inf, 7., inf],
[inf, inf, inf, 3., 4., 5., 6., inf, 8.],
[inf, inf, inf, inf, 4., 5., inf, 7., inf]])
编辑
假设一个无序的、非方阵的表示,我对我的代码做了一个小的改动,看起来像这样:
def create_adj_mat(x):
y = np.ones([np.max(x)+1,np.max(x)+1]) * np.inf #initialize
for I,i in enumerate(np.ravel(x)):
#get adjacent values of y and x points
d = x[max(0,I//x.shape[1]-1):min(x.shape[0],I//x.shape[1]+2),
max(0,I%x.shape[1]-1):min(x.shape[1],I%x.shape[1]+2)]
y[i,np.ravel(d)] = np.ravel(d)
np.fill_diagonal(y,np.inf) #remove i,i points
return y
然后,当您传递这样一个数组时:
d = np.array([[10,3],[5,12],[2,1]])
create_adj_mat(d)
array([[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf],
[inf, inf, 2., inf, inf, 5., inf, inf, inf, inf, inf, inf, 12.],
[inf, 1., inf, inf, inf, 5., inf, inf, inf, inf, inf, inf, 12.],
[inf, inf, inf, inf, inf, 5., inf, inf, inf, inf, 10., inf, 12.],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf],
[inf, 1., 2., 3., inf, inf, inf, inf, inf, inf, 10., inf, 12.],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf],
[inf, inf, inf, 3., inf, 5., inf, inf, inf, inf, inf, inf, 12.],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf],
[inf, 1., 2., 3., inf, 5., inf, inf, inf, inf, 10., inf, inf]])