汉明距离 python 改进

hamming distance python improvement

我正在尝试写汉明距离。
作为输入,我有两个矩阵 M1 和 M2,一个是 40x20,第二个是 50x20;它们包含 True/False。我需要计算每行之间的距离,因此 M1[0] 与 M2[0] 的距离,M1[0] 与 M2[1] 的距离 ... M1[39] 与 M2[49] 的距离。产生 40x50 结果矩阵。我的第一次尝试当然是像这样循环:

for x_i in range(X.shape[0]):
        for x_train_j in range(X_train.shape[0]):
            distance_results[x_i, x_train_j] = sum(np.logical_xor(x_array[x_i, :], x_train_array[x_train_j, :]))

它是正确的,但是,它对我的​​数据来说太慢了。我对乘法 M1.dot(M2.T) 有一些想法,它给出了正确的矩阵形状并一步求和,但是当需要乘法和求和 xor 时,所以:
1 * 1 = 1(需要 0 - 不好)
1 * 0 = 0(需要 1 - 不好)
0 * 1 = 0(需要 1 - 不好)
0 * 0 = 0(需要 0 - 即可)
你知道我怎样才能得到想要的结果吗?我想我想念一些数学来正确快速地完成它。 提前致谢。

M1.dot(M2.T) 在某种程度上可以被视为布尔逻辑的 AND。对于二进制逻辑 A xor B 等价于 (A and not B) or (not A and B) 所以你可以做一件事 --

M1.dot(M2.T):
1 * 1 = 1 
1 * 0 = 0 
0 * 1 = 0
0 * 0 = 0

(not M1).dot(M2.T):
0 * 1 = 0
0 * 0 = 0 
1 * 1 = 1
1 * 0 = 0

M1.dot(not M2.T):
1 * 0 = 0 
1 * 1 = 1
0 * 0 = 0
0 * 1 = 0

(not M1).dot(M2.T) or M1.dot(not M2.T):
0 * 1 || 1 * 0 = 0
0 * 0 || 1 * 1 = 1 
1 * 1 || 0 * 0 = 1
1 * 0 || 0 * 1 = 0

要对其进行编码,您需要注意在点之前抛出逻辑,以便计算总和。如果你点在 2 个逻辑数组上,你将不会得到你想要的结果。我只使用 -1 作为我的非运算符 ( True - 1 = 0, False - 1 = -1)。此外,这里的 'or' 实际上是一个总和,因为您正在考虑多个布尔值。最后,您的距离为负值,很容易用绝对值修复。

_A = [[ True,  True,  False],
      [ True,  False, True]]

_B = [[ True,  False, False],
      [ False, False, False],
      [ True,  True,  True ]]

预期输出: [[ 1, 2, 1], [ 1, 2, 1]]

A = numpy( _A, dtype=bool)
B = numpy( _B, dtype=bool)

numpy.absolute(numpy.dot(A,B.T-1) + numpy.dot(A-1, B.T))

>>>array([[1, 2, 1],
          [1, 2, 1]])