问题描述
我需要计算之间的汉明距离
- 我的参考数据集的形状为N0(行)x M0(列)-
Ref.csv
- 我的形状为N1(行)x M1(列)的测试数据集-
Tes.csv
结果矩阵的形状应为N0 x N1,其中包含参考的所有行和测试的所有行之间的汉明距离(作为新数据集中的列)
使用循环执行此操作可能会效率低下。
我正在使用的一些资源
from scipy.spatial.distance import hamming
理想情况下,我希望计算如下所示的汉明距离,这在计算上更便宜。下面的循环计算欧几里得距离。
def compute_distances_no_loops(Train,X):
dists = -2 * np.dot(X,Train.T) + np.sum(Train**2,axis=1) + np.sum(X**2,axis=1)[:,np.newaxis]
return dists
以下是您可以使用的DropBox上的csv数据集:HammingDistance
解决方法
让我们从一个通知开始:锤击的距离是 等于长度的序列。 由于您两个数组的列数均不同,因此我们 采用更通用的方法,即 Levenshtein 距离, 还考虑了插入和删除。
尽管提出了Levenshtein距离的概念以进行比较 字符串,事实证明它也可以应用于 数字。
我使用以下函数来计算Levenshtein距离:
def levDist(s1,s2):
if len(s1) < len(s2): return levDist(s2,s1)
if len(s2) == 0: return len(s1)
prev_row = range(len(s2) + 1)
for i,c1 in enumerate(s1):
curr_row = [i + 1]
for j,c2 in enumerate(s2):
curr_row.append(min(prev_row[j + 1] + 1,curr_row[j] + 1,prev_row[j] + (c1 != c2)))
prev_row = curr_row
return prev_row[-1]
为了测试我的代码,我将 Tes.csv 和 Res.csv 缩短为第一个 分别读取10行和4行,并阅读它们:
tes = np.loadtxt('Tes.csv',delimiter=',',encoding='utf-8')
ref = np.loadtxt('Ref.csv',encoding='utf-8')
实际计算如下:
result = np.zeros([tes.shape[0],ref.shape[0]],dtype=int)
iTes = 0
for tesRow in tes:
iRef = 0
for refRow in ref:
result[iTes,iRef] = levDist(tesRow.tolist(),refRow.tolist())
iRef += 1
iTes += 1
对于您的(缩小的)输入文件,我得到以下结果:
[[ 0 39 38 39]
[39 4 6 3]
[39 3 5 0]
[39 6 8 3]
[39 3 7 4]
[39 0 6 3]
[39 1 5 2]
[39 3 5 4]
[39 5 6 4]
[39 3 3 2]]