python - 查找相似度矩阵中不在对角线上的最高值

标签 python matrix numpy

假设我有以下 similarity matrix :

matrix = [[100.0, 66.666666666666671, 61.539999999999999, 59.260000000000005, 59.260000000000005, 82.61333333333333, 61.539999999999999, 61.539999999999999, 61.539999999999999, 78.259999999999991],
[66.666666666666671, 100.0, 91.306666666666672, 87.5, 87.5, 69.233333333333334, 91.306666666666672, 91.306666666666672, 91.306666666666672, 65.386666666666656],
[61.539999999999999, 91.306666666666672, 100.0, 88.0, 88.0, 70.373333333333335, 91.666666666666671, 91.666666666666671, 100.0, 66.666666666666671],
[59.260000000000005, 87.5, 88.0, 100.0, 84.620000000000005, 74.079999999999998, 95.833333333333329, 95.833333333333329, 88.0, 64.286666666666662],
[59.260000000000005, 87.5, 88.0, 84.620000000000005, 100.0, 67.859999999999999, 88.0, 88.0, 88.0, 64.286666666666662],
[82.61333333333333, 69.233333333333334, 70.373333333333335, 74.079999999999998, 67.859999999999999, 100.0, 76.926666666666662, 76.926666666666662, 76.926666666666662, 87.5],
[61.539999999999999, 91.306666666666672, 91.666666666666671, 95.833333333333329, 88.0, 76.926666666666662, 100.0, 100.0, 91.666666666666671, 66.666666666666671],
[61.539999999999999, 91.306666666666672, 91.666666666666671, 95.833333333333329, 88.0, 76.926666666666662, 100.0, 100.0, 91.666666666666671, 66.666666666666671],
[61.539999999999999, 91.306666666666672, 100.0, 88.0, 88.0, 76.926666666666662, 91.666666666666671, 91.666666666666671, 100.0, 66.666666666666671],
[78.259999999999991, 65.386666666666656, 66.666666666666671, 64.286666666666662, 64.286666666666662, 87.5, 66.666666666666671, 66.666666666666671, 66.666666666666671, 100.0]]

请注意,对角线上的值都等于 100.0,并且上三角等于下三角。

我想找到不在对角线上的五个不同最高值的索引。

目前我采用这种蛮力方式:

from collections import defaultdict
d = defaultdict(list)
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
      d[matrix[i][j]].append((i,j))

for value in sorted(d.keys(), reverse=True)[1:6]:
    print value, d[value]

这给出:

95.8333333333 [(3, 6), (3, 7), (6, 3), (7, 3)]
91.6666666667 [(2, 6), (2, 7), (6, 2), (6, 8), (7, 2), (7, 8), (8, 6), (8, 7)]
91.3066666667 [(1, 2), (1, 6), (1, 7), (1, 8), (2, 1), (6, 1), (7, 1), (8, 1)]
88.0 [(2, 3), (2, 4), (3, 2), (3, 8), (4, 2), (4, 6), (4, 7), (4, 8), (6, 4), (7, 4), (8, 3), (8, 4)]
87.5 [(1, 3), (1, 4), (3, 1), (4, 1), (5, 9), (9, 5)]

但这效率很低,因为我遍历整个矩阵,而我只需要遍历一半矩阵:对于最高值95.8333333333我只关心索引(3,6) (3,7)

有没有更有效的方法来做到这一点,也许使用 numpy?

最佳答案

from heapq import nlargest
from collections import defaultdict

d = defaultdict(list)

for i in xrange(len(matrix)):
    for j in xrange(i):
      d[matrix[i][j]].append((i, j))

for value, positions in nlargest(5, d.items(), key=lambda item: item[0]):
    print value, positions
  • 使用 xrange 代替 range
  • 仅循环 j 到 i - 1(如果 i = 0,则内部循环永远不会运行...)
  • 为了高效使用,不要对列表进行排序,而是使用 heapq 中的 nlargest 因为它为此使用堆数据结构。这对于大型矩阵来说应该很重要。

关于python - 查找相似度矩阵中不在对角线上的最高值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11115383/

相关文章:

python - 属性错误: 'Ui_Form' object has no attribute 'printHam_btn'

python - 矩阵操作 - 为什么正常循环会产生不同的结果?

matrix - 如何将四元数转换为matrix4形式的实数,原理是什么?

python - 在张量上计算为图中的 numpy 数组?

python - 在 Python 中获取 numpy/scipy 中的日志比率

python - Cython:python int 到 uint8_t

python glob匹配更广泛的范围

python - 无需重新计算即可获取字典键哈希

r - 如何按行中的值过滤表

python - Zip 参数 #2 必须支持迭代。为什么重新分配 ndarray 时会生成此错误?