Python 仅考虑非零值的numpy阵列之间的成对汉明距离

Python 仅考虑非零值的numpy阵列之间的成对汉明距离,python,python-3.x,numpy,hamming-distance,Python,Python 3.x,Numpy,Hamming Distance,我想计算2D numpy数组的成对汉明距离 我的数组是 A array([[-1, 0, -1, 0, -1, 0], [ 1, 0, 0, 0, 0, 0], [ 0, 0, 1, 1, 1, 0], [ 0, 0, -1, 1, 0, 0], [ 0, 0, 0, 0, -1, 0]], dtype=int8) 我想计算A行之间的汉明距离,但只考虑非零值。如果其中一个条目为零,我们不将其包含在

我想计算2D numpy数组的成对汉明距离

我的数组是

A
array([[-1,  0, -1,  0, -1,  0],
       [ 1,  0,  0,  0,  0,  0],
       [ 0,  0,  1,  1,  1,  0],
       [ 0,  0, -1,  1,  0,  0],
       [ 0,  0,  0,  0, -1,  0]], dtype=int8)
我想计算A行之间的汉明距离,但只考虑非零值。如果其中一个条目为零,我们不将其包含在计算中

我的输出应该是

B
array([[0, 1, 2, 0, 0],
       [1, 0, 0, 0, 0],
       [2, 0, 0, 1, 1],
       [0, 0, 1, 0, 0],
       [0, 0, 1, 0, 0]], dtype=int8) 

我觉得应该有一个更简单的方法来实现这一点(就速度而言,应该没问题,因为一切都是基于数组的,可读性有点难)。但这里有一个可行的解决方案:

from itertools import permutations

b = np.zeros((a.shape[0], a.shape[0]))
idx = np.array(list(permutations(range(a.shape[0]),2)))
b[tuple(idx.T)] = np.count_nonzero(np.logical_and(a[idx.T][0,:]-a[idx.T][1,:], np.logical_and(a[idx.T][0,:]!=0, a[idx.T][1,:]!=0)), axis=1)
首先使用
itertools
permutations
作为索引创建所有可能的行组合,然后针对每对行,在逻辑and中计算它们的非零值以及它们的非零值:

输出:

[[0. 1. 2. 0. 0.]
 [1. 0. 0. 0. 0.]
 [2. 0. 0. 1. 1.]
 [0. 0. 1. 0. 0.]
 [0. 0. 1. 0. 0.]]

如果数组只有0和1,则具有以下属性:
r1*r2
将在缺少的位置包含0,-1(元素不同)和+1(元素相同)。因此,您希望将所有可能的组合相乘,并计算每行少于零的条目数

您将产品与广播结合使用:

B = np.count_nonzero(A[:, None, :] * A[None, :, :] < 0, axis=-1)
如果要显式地写出条件,可以这样做

np.count_nonzero((A1 != A2) & (A1 != 0) & (A2 != 0), axis=-1)

你能定义海明距离吗?也许可以展示一个如何实现的循环,以避免歧义。数组是否只有0和1?有一种更简单的方法,可以保留数据类型。获取给定轴的所有组合的惯用方法是在前后使用None索引复制它。@mad物理学家我可以看出我可以用
a[,None,:]!=a
但我不知道如何排除零。请随意编辑我的帖子,我会学到更多。谢谢。我不想编辑你的作品。请看我的答案,我认为这是最简单的解决方案。
np.count_nonzero((A1 != A2) & (A1 != 0) & (A2 != 0), axis=-1)