Python如何生成两两汉明距离矩阵

2024-10-04 11:25:12 发布

您现在位置:Python中文网/ 问答频道 /正文

这里是Python的初学者。因此,我在尝试仅使用numpy库计算输入矩阵行之间的二进制成对hammington距离矩阵时遇到了困难。我应该避免循环并使用向量化。例如,如果我有类似的东西:

   [ 1,  0,  0,  1,  1,  0]
   [ 1,  0,  0,  0,  0,  0]
   [ 1,  1,  1,  1,  0,  0]

矩阵应该类似于:

^{pr2}$

即如果原始矩阵是A,而hamming距离矩阵是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.总和而不是np.count_非零但他们都给了我相似的东西。在


Tags: 答案numpynone距离lencountnp二进制
2条回答

因为我不明白的原因

(2 * np.inner(a-0.5, 0.5-a) + a.shape[1] / 2)

对于更大的阵列,似乎比@Psidom快得多:

^{pr2}$

对于一个非常小的例子,Psidom的速度要快一些:

a
# array([[1, 0, 0, 1, 1, 0],
#        [1, 0, 0, 0, 0, 0],
#        [1, 1, 1, 1, 0, 0]])

timeit(lambda: (a[:, None, :] != a).sum(2), number=100)
# 0.0004370050155557692
timeit(lambda: (2 * np.inner(a-0.5, 0.5-a) + a.shape[1] / 2), number=100)
# 0.00068191799800843

更新

部分原因似乎是浮动比其他数据类型快:

timeit(lambda: (0.5 * np.inner(2*a-1, 1-2*a) + a.shape[1] / 2), number=100)
# 0.7315902590053156
timeit(lambda: (0.5 * np.inner(2.0*a-1, 1-2.0*a) + a.shape[1] / 2), number=100)
# 0.12021801102673635

尝试此方法,沿axis = 1创建一个新轴,然后使用sum进行广播和计数真值或非零:

(arr[:, None, :] != arr).sum(2)

# array([[0, 2, 3],
#        [2, 0, 3],
#        [3, 3, 0]])

^{pr2}$

解释:

1)创建具有形状(3,1,6)的三维阵列

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)这会触发广播,因为它们的形状不匹配,并且2d数组arr首先沿着3d arrayarr[:,None,:]的0轴广播,然后对(3,6)的shape(1,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计算有多少个元素不相等,即trues给出了hamming距离。

相关问题 更多 >