列出levenshtein距离矩阵中的非对角线值

时间:2018-09-04 21:12:25

标签: python pandas levenshtein-distance

使用以下数据,如何创建一个以'id'列为索引,第二列包含一个Levenshtein距离矩阵的非对角值列表的DataFrame,该列对应于每个id?

d = {'id':[1,1,1,2,2],'string':['roundys','roundys','ppg','brewers','cubs']}
df = pd.DataFrame(data=d)

目标是生成一个看起来像

的DataFrame
df_diag = pd.DataFrame({'id':[1,2],'diag_val':['0.0,7.0,7.0','6.0']})

我已经构建了一些可以处理单个列表的粗略部分,但是无法通过“ id”遍历多个列表。我使用大熊猫作为“ pd”,使用numpy作为“ np”,与莱文施泰因的距离作为“ dist”

第1步创建测试列表

aTest = ['roundys','roundys','ppg']

第2步创建从aTest返回编辑距离矩阵的函数

def editDistance(list_o_strings):
    matrix = np.zeros(shape = (len(list_o_strings),len(list_o_strings)))

    for i in range(len(list_o_strings)):
        for j in range(i, len(list_o_strings)):
            matrix[i][j] = dist(list_o_strings[i],list_o_strings[j])
    for i in range(0, len(list_o_strings)):
        for j in range(0,len(list_o_strings)):
            if i == j:
                matrix[i][j] = 0
            elif i > j:
                matrix[i][j] = matrix[j][i]
    return matrix

第3步创建返回非对角线编辑距离项的函数

def selectElements(matrix):
    ws = []
    for i in range(0, matrix.shape[0]):
        for j in range(0, matrix.shape[1]):
            if i <> j and i>j:
                ws.append(matrix[i,j])
    return ws 

第4步测试示例列表

testDistance = editDistance(aTest)
testOffDiag = selectElements(testDistance)

我的下一步是对数据集中的唯一ID值进行迭代。我创建了一个新的ID为ID的数据框,并与一个字符串列表配对

df1 = df.groupby('id').agg(lambda x: ','.join(x))

我试图让功能遍历id项的尝试失败了,有什么建议吗?

2 个答案:

答案 0 :(得分:1)

通过安装pip,您可以获得Levenshtein的距离

pip install python-Levenshtein

然后您可以执行类似的操作

from Levenshtein import distance
from itertools import combinations

def lm(a):
  return [distance(*b) for b in combinations(a, 2)]

df.groupby('id').string.apply(lm).reset_index(name='diag_val')

   id   diag_val
0   1  [0, 7, 7]
1   2        [6]

def lm(a):
  return ','.join([str(distance(*b)) for b in combinations(a, 2)])

df.groupby('id').string.apply(lm).reset_index(name='diag_val')

   id diag_val
0   1    0,7,7
1   2        6

答案 1 :(得分:0)

Scipy具有scipy.spatial.distance.pdist函数,可让您计算n维空间中元素之间的成对距离。该功能还允许自定义metric参数。

我们可以将您的值以及使用python-Levenshtein库计算出的指标函数输入该函数。

设置

from Levenshtein import distance
from scipy.spatial.distance import pdist

使用pdist和自定义指标:

def lm(x):
    return pdist(x.values.reshape(-1, 1), lambda x,y: distance(x[0],y[0]))

res = pd.DataFrame(
    [(i, lm(g)) for i, g in df.groupby('id').string],
    columns=['id', 'diag_val']
)

   id         diag_val
0   1  [0.0, 7.0, 7.0]
1   2            [6.0]