此处为 Python 初学者。因此,我在尝试仅使用 numpy 库计算输入矩阵的行之间生成的二进制成对汉明顿距离矩阵时遇到了麻烦。我应该避免循环并使用矢量化。例如,如果我有类似的东西:
[ 1, 0, 0, 1, 1, 0]
[ 1, 0, 0, 0, 0, 0]
[ 1, 1, 1, 1, 0, 0]
矩阵应该是这样的:
[ 0, 2, 3]
[ 2, 0, 3]
[ 3, 3, 0]
即如果原始矩阵为A,汉明距离矩阵为B。B[0,1] = 汉明距离(A[0] 和A[1])。在这种情况下,答案是 2,因为它们只有两个不同的元素。
所以我的代码是这样的
def compute_HammingDistance(X):
hammingDistanceMatrix = np.zeros(shape = (len(X), len(X)))
hammingDistanceMatrix = np.count_nonzero ((X[:,:,None] != X[:,:,None].T))
return hammingDistanceMatrix
但是它似乎只是返回一个标量值而不是预期的矩阵。我知道我可能在数组/矢量广播方面做错了,但我不知道如何修复它。我试过使用 np.sum 而不是 np.count_nonzero 但它们几乎都给了我类似的东西。
请您参考如下方法:
尝试这种方法,沿 axis = 1 创建一个新轴,然后使用 sum 进行广播并计算真值或非零值:
(arr[:, None, :] != arr).sum(2)
# array([[0, 2, 3],
# [2, 0, 3],
# [3, 3, 0]])
def compute_HammingDistance(X):
return (X[:, None, :] != X).sum(2)
解释:
1) 创建一个形状为 (3,1,6) 的 3d 数组
arr[:, None, :]
#array([[[1, 0, 0, 1, 1, 0]],
# [[1, 0, 0, 0, 0, 0]],
# [[1, 1, 1, 1, 0, 0]]])
2) 这是一个二维数组,形状为 (3, 6)
arr
#array([[1, 0, 0, 1, 1, 0],
# [1, 0, 0, 0, 0, 0],
# [1, 1, 1, 1, 0, 0]])
3) 这会触发广播,因为它们的形状不匹配,并且二维数组 arr 首先沿 3d 数组 arr[:, None, :]< 的 0 轴广播/em>,然后我们将形状为 (1, 6) 的数组针对 (3, 6) 进行广播。两个广播步骤一起对原始数组进行笛卡尔比较。
arr[:, None, :] != arr
#array([[[False, False, False, False, False, False],
# [False, False, False, True, True, False],
# [False, True, True, False, True, False]],
# [[False, False, False, True, True, False],
# [False, False, False, False, False, False],
# [False, True, True, True, False, False]],
# [[False, True, True, False, True, False],
# [False, True, True, True, False, False],
# [False, False, False, False, False, False]]], dtype=bool)
4) 沿第三轴的sum 计算有多少元素不相等,即给出汉明距离的真值。
