Это решение использует 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()
предназначен для обработки одной строки запроса и применения переданного алгоритма оценки к этому запросу и предоставленным параметрам соответствия.По этой причине вам нужно будет сравнить этот запрос со всеми 70000 вариантов совпадения (так, как вы сейчас настраиваете код).Поэтому вы будете оценивать len(match_options)**2
(или 4 900 000 000) сравнений строк.Поэтому я думаю, что наилучшего улучшения производительности можно достичь, ограничив потенциальные параметры сопоставления с помощью более обширной логики в функции find_match()
, например, установив, что параметры сопоставления начинаются с той же буквы, что и запрос, и т. Д.