我有一个包含城市名称的列,这些名称可能包含拼写错误。
try: from StringIO import StringIOexcept ImportError: from io import StringIOmyst="""1 Mumbai2 Delhi3 Delhi4 Mumbai5 Mumbai6 Delhi7 Dolhi"""u_cols=['customer_id', 'city']myf = StringIO(myst)import pandas as pddf = pd.read_csv(StringIO(myst), sep=' ', names = u_cols)
当我按城市分组时,我可以看到拼写错误…
df['city'].value_counts()Delhi 3Mumbai 3Dolhi 1
我可以很容易地使用replace方法来纠正它,像这样…
df.replace({'Dolhi': 'Delhi'})['city'].value_counts()
但没有办法知道可能的拼写错误。如果有两个相似的单词,则认为计数较高的单词是正确的。因此,在这种情况下,“Delhi”是正确的,而“Dolhi”是错误的。是否有可能对这个数据框数据应用这种“智能”?
回答:
您可以计算每个城市对之间的Levenshtein距离,这是一个衡量两个字符串相似性的指标。基本上,每次您需要进行的更改(例如更改字符,或添加/删除字符)都会使Levenshtein距离增加1。nltk
包包含一个edit_distance()
函数,它返回Levenshtein距离。
您可以使用itertools.combinations()
遍历所有独特的城市对,并检查Levenshtein距离是否低于某个魔法阈值,例如在这个例子中是1
。请注意,这个阈值需要一些手动调整,以免合并不同的城市名称,同时仍然捕获所有拼写错误。
然后,您可以通过比较它们在数据集中使用的频率来找出正确的名称(下面的main_name
)和错误的名称(下面的mistake
)。当然,这是在假设人们大多数时候会正确书写城市名称的情况下进行的。
import itertoolsfrom nltk.metrics import edit_distanceMAGIC_THRESHOLD = 1city_names = df['city'].value_counts()for name_a, name_b in itertools.combinations(city_names.index, 2): if edit_distance(name_a, name_b) <= MAGIC_THRESHOLD: count_a, count_b = city_names[name_a], city_names[name_b] main_name, mistake = (name_a, name_b) if count_a > count_b else (name_b, name_a) df = df.replace({mistake: main_name})print(df['city'].value_counts())
这给我们的结果是:
Delhi 4Mumbai 3