亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

向量化或加速 PANDAS 列上的 Fuzzywuzzy 字符串匹配

向量化或加速 PANDAS 列上的 Fuzzywuzzy 字符串匹配

慕容708150 2021-07-02 10:11:15
我正在嘗試在充滿組織名稱的 PANDAS 列中尋找潛在匹配項。我目前正在使用 iterrows() 但它在具有 ~70,000 行的數據幀上非常慢。在查看了 StackOverflow 之后,我嘗試實現一個 lambda 行(應用)方法,但這似乎幾乎沒有加快速度,如果有的話。數據框的前四行如下所示:index  org_name0   cliftonlarsonallen llp minneapolis MN1   loeb and troper llp newyork NY2   dauby o'connor and zaleski llc carmel IN3   wegner cpas llp madison WI以下代碼塊有效,但需要大約五天的時間來處理:org_list = df['org_name']from fuzzywuzzy import processfor index, row in df.iterrows():    x = process.extract(row['org_name'], org_list, limit=2)[1]    if x[1]>93:        df.loc[index, 'fuzzy_match'] = x[0]        df.loc[index, 'fuzzy_match_score'] = x[1]實際上,對于每一行,我將組織名稱與所有組織名稱的列表進行比較,取前兩個匹配項,然后選擇第二個最佳匹配項(因為頂部匹配項將是相同的名稱),然后設置一個條件分數必須高于 93 才能創建新列。我創建附加列的原因是我不想簡單地替換值——我想先仔細檢查結果。有沒有辦法加快這個速度?我閱讀了幾篇博客文章和 StackOverflow 問題,這些問題討論了“向量化”這段代碼,但我的嘗試失敗了。我還考慮過簡單地創建一個 70,000 x 70,000 Levenshtein 距離矩陣,然后從中提取信息。有沒有更快的方法來為列表或 PANDAS 列中的每個元素生成最佳匹配?
查看完整描述

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()函數中更廣泛的邏輯限制潛在的匹配選項來實現最佳性能改進,例如強制匹配選項以與查詢相同的字母開頭等。


查看完整回答
反對 回復 2021-07-06
?
慕容3067478

TA貢獻1773條經驗 獲得超3個贊

不建議在數據幀上使用 iterrows(),您可以使用 apply() 代替。但這可能不會大大加快速度。慢的是fuzzywuzzy 的提取方法,其中將您的輸入與所有70k 行進行比較(字符串距離方法在計算上很昂貴)。因此,如果您打算堅持使用fuzzywuzzy,一個解決方案是將您的搜索限制為例如僅具有相同首字母的搜索。或者,如果您的數據中有另一列可用作提示(州、城市、...)


查看完整回答
反對 回復 2021-07-06
  • 3 回答
  • 0 關注
  • 647 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號