我有一组N维向量。
data = np.array([[5, 6, 1], [2, 0, 8], [4, 9, 3]])
In [1]: data
Out[1]:
array([[5, 6, 1],
[2, 0, 8],
[4, 9, 3]])
我正在使用sklearn的pairwise_distances
function来计算距离值矩阵。请注意,此矩阵关于对角线是对称的。
dists = pairwise_distances(data)
In [2]: dists
Out[2]:
array([[ 0. , 9.69535971, 3.74165739],
[ 9.69535971, 0. , 10.48808848],
[ 3.74165739, 10.48808848, 0. ]])
我需要与此矩阵dists
中的前N个值对应的索引,因为这些索引将对应data
中的成对索引,这些索引表示它们之间距离最大的向量。
我已尝试执行np.argmax(np.max(distances, axis=1))
获取每行中最大值的索引,并np.argmax(np.max(distances, axis=0))
获取每列中最大值的索引,但请注意:
In [3]: np.argmax(np.max(dists, axis=1))
Out[3]: 1
In [4]: np.argmax(np.max(dists, axis=0))
Out[4]: 1
和:
In [5]: dists[1, 1]
Out[5]: 0.0
因为矩阵关于对角线是对称的,并且因为argmax返回它找到的具有最大值的第一个索引,所以我最终得到行中的对角线中的单元格与存储最大值的列匹配,而不是顶部值本身的行和列。
此时我确信我可以编写更多代码来查找我正在寻找的值,但肯定有一种更简单的方法可以做我想做的事情。所以我有两个或多或少相同的问题:
如何在矩阵中找到与前N个值对应的索引,或,如何找到前N个成对距离的向量从一组向量?
答案 0 :(得分:6)
我拉扯,argsort,然后解开。我并不是说这是最好的方式,只是这是我发生的第一种方式,而且在有人发布更明显的内容之后,我可能会羞愧地删除它。 : - )
那就是说(选择前两个值,任意):
In [73]: dists = sklearn.metrics.pairwise_distances(data)
In [74]: dists[np.tril_indices_from(dists, -1)] = 0
In [75]: dists
Out[75]:
array([[ 0. , 9.69535971, 3.74165739],
[ 0. , 0. , 10.48808848],
[ 0. , 0. , 0. ]])
In [76]: ii = np.unravel_index(np.argsort(dists.ravel())[-2:], dists.shape)
In [77]: ii
Out[77]: (array([0, 1]), array([1, 2]))
In [78]: dists[ii]
Out[78]: array([ 9.69535971, 10.48808848])
答案 1 :(得分:1)
作为对DSM以前非常好的答案的一个略微改进,如果不考虑N最大的阶数,则使用np.argsort()
会更有效,而不是使用np.argpartition()
。
用索引arr
对数组i
进行分区会重新排列元素,以使索引i
处的元素第i个最大,而左边的元素较大,而右边的元素较小。左侧和右侧的分区不一定要排序。这样做的好处是它可以线性运行。