【发布时间】:2020-05-17 03:03:39
【问题描述】:
我有 2 个不同的数据框,我正在尝试匹配字符串列(名称)
以下只是一些 DF 的示例
df1 (127000,3)
Code Name PostalCode
150 Maarc 47111
250 Kirc 41111
170 Moic 42111
140 Nirc 44111
550 Lacter 47111
df2 (38000,3)
Code NAME POSTAL_CODE
150 Marc 47111
250 Kikc 41111
170 Mosc 49111
140 NiKc 44111
550 Lacter 47111
目的是创建另一个DF3,如下所示
Code NAME Best Match Score
150 Marc Maarc 0.9
250 Karc Kirc 0.9
以下代码给出了预期的输出
import difflib
from functools import partial
f = partial(difflib.get_close_matches, possibilities= df1['Name'].tolist(), n=1)
matches = df2['NAME'].map(f).str[0].fillna('')
scores = [difflib.SequenceMatcher(None, x, y).ratio()
for x, y in zip(matches, df2['NAME'])]
df3 = df2.assign(best=matches, score=scores)
df3.sort_values(by='score')
问题
仅匹配 2 行的这些字符串大约需要 30 秒。此任务必须针对 1K 行完成,这需要数小时!
问题
如何加快代码速度? 我在想像fetchall这样的东西?
编辑
连fuzzywuzzy库都试过了,比difflib用的时间长,代码如下:
from fuzzywuzzy import fuzz
def get_fuzz(df, w):
s = df['Name'].apply(lambda y: fuzz.token_set_ratio(y, w))
idx = s.idxmax()
return {'Name': df['Name'].iloc[idx], 'CODE': df['Code'].iloc[idx], 'Value': s.max()}
df2['NAME'].apply(lambda x: get_fuzz(df1, x))
df2 = df2.assign(search= df2['NAME'].apply(lambda x: get_fuzz(df1, x)))
【问题讨论】:
-
很遗憾,我认为 difflib 不是完成这项任务的正确工具,它的速度并不快
-
也许您可以尝试使用
sklearn模块构建距离矩阵或类似的东西。对于您的情况,levenshtein 距离可能很有趣。
标签: python string pandas dictionary