使用rapidfuzz计算DataFrame两列Levenshtein距离报KeyError如何解决
问题场景
现有分号分隔的CSV文件,原始内容如下:
ID; name1; name2 1; John Doe; John Does 2; Mike Johnson; Mike Jonson 3; Leon Mill; Leon Miller 4; Jack Jo; Jack Joe
需求为逐行计算name1与name2字段的Levenshtein距离,将结果存入新增的ld列,预期输出格式:
ID; name1; name2;ld 1; John Doe; John Does;1 2; Mike Johnson; Mike Jonson;1 3; Leon Mill; Leon Miller;2 4; Jack Jo; Jack Joe;1
编写的初始实现代码如下:
from rapidfuzz.distance import Levenshtein import pandas as pd df = pd.read_csv(r'C:\Users\myuser\Downloads\Testfile.csv', sep=";") print(df) df['ld']=df.apply(lambda x: Levenshtein.distance(df['name1'], df['name2']), axis=1)
运行代码后触发报错:KeyError: 'name1'
错误原因
代码一共存在两个问题,其中第一个直接触发了KeyError:
- 列名读取带前置空格:原始CSV的分隔符
;后紧跟空格,读取时仅指定sep=";"会把分隔符后的空格计入列名,实际生成的列名是name1、name2(开头带空格),直接访问df['name1']找不到对应列,就会抛出键错误。 - apply逻辑写法错误:指定
axis=1时,lambda接收的参数x是当前行的Series对象,代码中没有从行对象取值,反而把整个DataFrame的两列全量数据传入距离计算函数,就算修复列名问题,也无法得到逐行计算的正确结果。
修正方案
- 先处理列名空格问题,二选一即可:
- 读取文件时增加
skipinitialspace=True参数,自动跳过分隔符后的前置空格,直接得到干净的列名:df = pd.read_csv(r'C:\Users\myuser\Downloads\Testfile.csv', sep=";", skipinitialspace=True) - 读取完成后批量给所有列名去除首尾空格:
df.columns = df.columns.str.strip()
- 读取文件时增加
- 修正逐行计算的取值逻辑,从行对象中获取对应字段的值:
df['ld'] = df.apply(lambda x: Levenshtein.distance(x['name1'], x['name2']), axis=1)
性能提示:如果处理的数据集量级较大,逐行apply的循环效率偏低,可以改用列表推导式直接对两列做逐对计算,速度会有明显提升:
df['ld'] = [Levenshtein.distance(a, b) for a, b in zip(df['name1'], df['name2'])]
计算完成后如果需要导出和原格式一致的分号分隔文件,可以使用如下命令:
df.to_csv('result.csv', sep=";", index=False)
内容的提问来源于stack exchange,提问作者PSt
相关产品推荐
相关产品推荐

