3 回答

TA贡献1799条经验 获得超9个赞
此解决方案利用apply()并应展示合理的性能改进。随意使用scorer并更改threshold以满足您的需求:
import pandas as pd, numpy as np
from fuzzywuzzy import process, fuzz
df = pd.DataFrame([['cliftonlarsonallen llp minneapolis MN'],
['loeb and troper llp newyork NY'],
["dauby o'connor and zaleski llc carmel IN"],
['wegner cpas llp madison WI']],
columns=['org_name'])
org_list = df['org_name']
threshold = 40
def find_match(x):
match = process.extract(x, org_list, limit=2, scorer=fuzz.partial_token_sort_ratio)[1]
match = match if match[1]>threshold else np.nan
return match
df['match found'] = df['org_name'].apply(find_match)
返回:
org_name match found
0 cliftonlarsonallen llp minneapolis MN (wegner cpas llp madison WI, 50, 3)
1 loeb and troper llp newyork NY (wegner cpas llp madison WI, 46, 3)
2 dauby o'connor and zaleski llc carmel IN NaN
3 wegner cpas llp madison WI (cliftonlarsonallen llp minneapolis MN, 50, 0)
如果你只想返回匹配的字符串本身,那么你可以修改如下:
match = match[0] if match[1]>threshold else np.nan
我在此处添加了与列表理解相关的 @user3483203 评论作为替代选项:
df['match found'] = [find_match(row) for row in df['org_name']]
请注意,process.extract()它旨在处理单个查询字符串并将传递的评分算法应用于该查询和提供的匹配选项。因此,您必须针对所有 70,000 个匹配选项(您当前设置代码的方式)评估该查询。因此,您将评估len(match_options)**2(或 4,900,000,000)字符串比较。因此,我认为可以通过find_match()函数中更广泛的逻辑限制潜在的匹配选项来实现最佳性能改进,例如强制匹配选项以与查询相同的字母开头等。

TA贡献1773条经验 获得超3个赞
不建议在数据帧上使用 iterrows(),您可以使用 apply() 代替。但这可能不会大大加快速度。慢的是fuzzywuzzy 的提取方法,其中将您的输入与所有70k 行进行比较(字符串距离方法在计算上很昂贵)。因此,如果您打算坚持使用fuzzywuzzy,一个解决方案是将您的搜索限制为例如仅具有相同首字母的搜索。或者,如果您的数据中有另一列可用作提示(州、城市、...)
添加回答
举报