问题描述
有人可以帮助我了解如何根据所有行之间的欧几里德距离(即 0 和 1、0 和 2、.. 1 和 2、...)从 numpy 数组生成加权邻接矩阵?
给出以下带有输入矩阵(5,4)的示例:
matrix = [[2,10,9,6],[5,1,4,7],[3,2,0],[10,20,4],[17,3,5,18]]
我想获得一个包含节点之间最小距离的加权邻接矩阵 (5,5),即
if dist(row0,row1)= 10,77 and dist(row0,row2)= 12,84,--> the output matrix will take the first distance as a column value.
from scipy.spatial.distance import cdist
dist = cdist( matrix,matrix,metric='euclidean')
我得到以下结果:
array([[ 0.,10.77032961,12.84523258,15.23154621,20.83266666],[10.77032961,0.,7.93725393,20.09975124,16.43167673],[12.84523258,19.72308292,23.17326045],[15.23154621,23.4520788 ],[20.83266666,16.43167673,23.17326045,23.4520788,0. ]])
但我还不知道如何指定我们为每个节点选择 2 个邻居的邻居数量。例如,我们定义邻居的数量 N = 2,然后对于每一行,我们只选择两个最小距离的两个邻居,我们得到结果:
[[ 0.,0 ],0. ]]
解决方法
假设 a
是您的欧几里得距离矩阵,您可以使用 np.argpartition
来选择每行 n
的最小值/最大值。请记住,对角线始终为 0 并且欧几里得距离是非负的,因此要在每行中保留两个最近的点,您需要每行保留 3 分钟(包括对角线上的 0)。然而,如果你想做最大,这不成立。
a[np.arange(a.shape[0])[:,None],np.argpartition(a,3,axis=1)[:,3:]] = 0
输出:
array([[ 0.,10.77032961,12.84523258,0.,0. ],[10.77032961,7.93725393,[12.84523258,[15.23154621,19.72308292,[20.83266666,16.43167673,0. ]])
,
您可以使用这种更简洁的解决方案从矩阵中获取最小的 n。尝试以下操作 -
dist.argsort(1).argsort(1)
在轴 = 1 上创建一个排名顺序(最小为 0,最大为 4),np.where 对其进行过滤或将其替换为 0。
np.where(dist.argsort(1).argsort(1) <= 2,dist,0)
array([[ 0.,0. ]])
这适用于任何轴,或者如果您想要矩阵中的 nlargest 或 nsmallest。