【发布时间】:2017-10-31 11:30:45
【问题描述】:
给定两个矩阵 X1 (N,3136) 和 X2 (M,3136)(其中每行中的每个元素都是二进制数),我试图计算汉明距离,以便将 X1 中的每个元素与所有X2 中的行,结果矩阵为 (N,M)。
我已经为它写了两个函数(第一个在 numpy 的帮助下,另一个没有 numpy):
def hamming_distance(X, X_train):
array = np.array([np.sum(np.logical_xor(x, X_train), axis=1) for x in X])
return array
def hamming_distance2(X, X_train):
a = len(X[:,0])
b = len(X_train[:,0])
hamming_distance = np.zeros(shape=(a, b))
for i in range(0, a):
for j in range(0, b):
hamming_distance[i,j] = np.count_nonzero(X[i,:] != X_train[j,:])
return hamming_distance
我的问题是上层函数比我使用两个 for 循环的下层函数慢得多。是否可以改进第一个功能,以便我只使用一个循环?
PS。对不起,我的英语不是我的母语,虽然我已经尽力了!
【问题讨论】:
-
So learn from it (
(u != v).mean())。 -
(u != v).mean()不会比当前版本更有效,因为循环仍然是必要的。 N和M有多大?也许计算所有与广播的成对比较,并仅对必要的部分进行切片。不过,它可能很容易填满你的记忆。 -
这只是表明 numpy 不是魔法仙尘;如果您正确使用它,它只会有助于提高性能。你的第二个也使用 numpy。
-
我失败的尝试是使用点积,因为这两个操作的相似之处。给定两个二进制矩阵,如果将其中一个与 (1-other) 相乘,它会给出不同条目的数量,其中第一个为 1,另一个为零。所以
(1-arr1).dot(arr2.T) + arr1.dot(1-arr2.T)实际上给出了汉明距离。它比循环快吗?很不幸的是,不行。 :) -
@ayhan 为了获得最佳性能,我们需要利用具有浮点值的 BLAS。将基于 float32 转换的数组的点作为答案发布。它以很大的优势获胜。
标签: python numpy matrix vectorization hamming-distance