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,一個解決方案是將您的搜索限制為例如僅具有相同首字母的搜索。或者,如果您的數據中有另一列可用作提示(州、城市、...)
添加回答
舉報