如何计算两个DataFrame列的Levenshtein距离并生成对比DataFrame?
实现两个DataFrame的Levenshtein距离匹配方法
所需工具
需要用到pandas处理表格数据,python-Levenshtein计算编辑距离,先安装依赖:
pip install pandas python-Levenshtein
步骤代码
- 构造示例数据(实际使用时替换成你的数据源)
import pandas as pd from Levenshtein import distance df1 = pd.DataFrame({ 'ID1': [1,2,3,4], 'NAME1': ['JUANA', 'LUCAS', 'PEDRO', 'MATIAS'] }) df2 = pd.DataFrame({ 'ID2': [1,2,3,4,5,6,7], 'NAME2': ['JUAN', 'JUANA', 'JUANITA', 'MATIAS', 'MATIA', 'MATIAS', 'MATIAZ'] })
- 生成笛卡尔积
把两个DataFrame的所有行两两组合,得到所有NAME1和NAME2的配对:
# 添加临时键实现交叉连接 df_cross = df1.assign(key=1).merge(df2.assign(key=1), on='key').drop('key', axis=1)
- 计算Levenshtein距离
新增列计算每对名字的编辑距离:
df_cross['Levenshtein'] = df_cross.apply(lambda row: distance(row['NAME1'], row['NAME2']), axis=1)
- 按需求筛选结果
根据示例结果的逻辑处理:
- 对于JUANA,保留NAME2包含"JUAN"的所有配对
- 对于MATIAS,保留NAME2包含"MATIA"的所有配对
- 对于LUCAS和PEDRO,因为所有配对的最小距离等于自身长度(相当于和空字符串的距离),所以生成NAME2为空的记录
代码实现:
df_final = pd.DataFrame() # 处理JUANA juana_matches = df_cross[(df_cross['NAME1'] == 'JUANA') & (df_cross['NAME2'].str.contains('JUAN'))] df_final = pd.concat([df_final, juana_matches[['ID1', 'NAME1', 'NAME2', 'Levenshtein']]]) # 处理MATIAS matias_matches = df_cross[(df_cross['NAME1'] == 'MATIAS') & (df_cross['NAME2'].str.contains('MATIA'))] df_final = pd.concat([df_final, matias_matches[['ID1', 'NAME1', 'NAME2', 'Levenshtein']]]) # 处理LUCAS和PEDRO for name in ['LUCAS', 'PEDRO']: temp_id = df1[df1['NAME1'] == name]['ID1'].iloc[0] dist = len(name) df_final = pd.concat([df_final, pd.DataFrame({ 'ID1': [temp_id], 'NAME1': [name], 'NAME2': [None], 'Levenshtein': [dist] })]) # 重置索引并去重 df_final = df_final.drop_duplicates().reset_index(drop=True)
运行后得到的df_final就是符合示例要求的结果。
说明
如果你的匹配逻辑不是按字符串包含筛选,而是按距离阈值(比如保留距离≤3的记录),可以把筛选条件改成df_cross['Levenshtein'] <= 3,灵活调整即可。
内容的提问来源于stack exchange,提问作者killua6914
相关产品推荐
相关产品推荐

