仅使用 for 循环计算行距离矩阵

Compute row distance matrix using only for loops

我一直在尝试从不同的二进制数组计算距离矩阵,我只能使用 for 循环来解决这个问题...

问题包括以下内容;想象一下,我有一个由不同行构建的二进制矩阵,如下所示,在这种情况下维度为 n=3,m=3:

np.matrix([[0,0,0],
           [1,0,1],
           [1,1,1]])

我想通过在每行上添加不同位置的数量来实现以下对称矩阵:

np.matrix([[0,2,3],
           [2,0,1],
           [3,1,0]])

我一直在尝试通过 2 个 for 循环并在 2 个位置为 != 时添加,但我不知道如何正确地迭代这些向量...

有什么帮助吗?

如果我没理解错的话,你可以这样做:

import numpy as np

mat = np.matrix([[0,0,0],
                 [1,0,1],
                 [1,1,1]])

result = np.zeros(np.shape(mat))

nrows, ncols = np.shape(mat)
for r in range(nrows):
    # We only need to compare the upper triangular part of the matrix. 
    for i in range(r+1, nrows):
        for j in range(ncols):
            result[r, i] += mat[r, j] != mat[i, j]
            
# Here we copy the upper triangular part to lower triangular to make it symmetric.
result = result + result.T 

print(result)
array([[0, 2, 3],
       [2, 0, 1],
       [3, 1, 0]])

如果你至少可以使用一些 numpy 函数:

# You can also iterate matrices row by row.
for i, row in enumerate(mat):
    # Sum differences. mat != row already calculates the differences with the whole matrix.
    result[i, :] = np.sum(mat != row, axis=1).transpose()
print(result)
array([[0, 2, 3],
       [2, 0, 1],
       [3, 1, 0]])

如果你想看到一个巧妙的技巧,这里是你如何在不使用 for 循环迭代的情况下做到这一点。以下代码使用“广播”。我们向数组添加一个维度,以便使用每一行自动完成比较:

# For this trick we need to convert the matrix to an array.
mat_arr = np.asarray(mat)
result_broadcasting = np.sum(mat_arr != mat_arr[:, None], axis=2)
print(result_broadcasting)
array([[0, 2, 3],
       [2, 0, 1],
       [3, 1, 0]])