簡體   English   中英

跨數據框列應用模糊匹配並將結果保存在新列中

[英]Apply fuzzy matching across a dataframe column and save results in a new column

我有兩個數據框,每個數據框都有不同的行數。 下面是每個數據集中的幾行

df1 =
     Company                                   City         State  ZIP
     FREDDIE LEES AMERICAN GOURMET SAUCE       St. Louis    MO     63101
     CITYARCHRIVER 2015 FOUNDATION             St. Louis    MO     63102
     GLAXOSMITHKLINE CONSUMER HEALTHCARE       St. Louis    MO     63102
     LACKEY SHEET METAL                        St. Louis    MO     63102

df2 = 
     FDA Company                    FDA City    FDA State   FDA ZIP
     LACKEY SHEET METAL             St. Louis   MO          63102
     PRIMUS STERILIZER COMPANY LLC  Great Bend  KS          67530
     HELGET GAS PRODUCTS INC        Omaha       NE          68127
     ORTHOQUEST LLC                 La Vista    NE          68128

我使用combined_data = pandas.concat([df1, df2], axis = 1)並排加入了它們。 我的下一個目標是使用來自fuzzy wuzzy模塊的幾個不同匹配命令將df1['Company']下的每個字符串與df2['FDA Company']下的每個字符串進行比較,並返回最佳匹配的值及其名稱。 我想將它存儲在一個新列中。 例如,如果我在df1['Company']df2['FDA Company'] LACKY SHEET METALLACKY SHEET METAL fuzz.ratiofuzz.token_sort_ratio ,它會返回最佳匹配是LACKY SHEET METAL ,得分為100 ,這然后將保存在combined data的新列下。 結果看起來像

combined_data =
     Company                                   City         State  ZIP      FDA Company                     FDA City    FDA State   FDA ZIP     fuzzy.token_sort_ratio    match    fuzzy.ratio         match
     FREDDIE LEES AMERICAN GOURMET SAUCE       St. Louis    MO     63101    LACKEY SHEET METAL              St. Louis   MO          63102       LACKEY SHEET METAL        100      LACKEY SHEET METAL  100
     CITYARCHRIVER 2015 FOUNDATION             St. Louis    MO     63102    PRIMUS STERILIZER COMPANY LLC   Great Bend  KS          67530
     GLAXOSMITHKLINE CONSUMER HEALTHCARE       St. Louis    MO     63102    HELGET GAS PRODUCTS INC         Omaha       NE          68127
     LACKEY SHEET METAL                        St. Louis    MO     63102    ORTHOQUEST LLC                  La Vista    NE          68128

我試着做

combined_data['name_ratio'] = combined_data.apply(lambda x: fuzz.ratio(x['Company'], x['FDA Company']), axis = 1) 

但是由於列的長度不同而出錯。

我難住了。 我怎樣才能做到這一點?

我說不清你在做什么。 這就是我要做的。

from fuzzywuzzy import fuzz
from fuzzywuzzy import process

創建一系列要比較的元組:

compare = pd.MultiIndex.from_product([df1['Company'],
                                      df2['FDA Company']]).to_series()

創建一個特殊的函數來計算模糊度量並返回一個系列。

def metrics(tup):
    return pd.Series([fuzz.ratio(*tup),
                      fuzz.token_sort_ratio(*tup)],
                     ['ratio', 'token'])

metrics應用於compare系列

compare.apply(metrics)

在此處輸入圖片說明

有很多方法可以完成下一部分:

獲取與df1每一行最接近的匹配

compare.apply(metrics).unstack().idxmax().unstack(0)

在此處輸入圖片說明

獲取與df2每一行最接近的匹配項

compare.apply(metrics).unstack(0).idxmax().unstack(0)

在此處輸入圖片說明

我已經通過並行處理在 Python 中實現了代碼,這將比串行計算快得多。 此外,在模糊度量分數超過閾值的情況下,只有那些計算是並行執行的。 請參閱以下鏈接以獲取代碼:

https://github.com/ankitcoder123/Important-Python-Codes/blob/main/Faster%20Fuzzy%20Match%20between%20two%20columns/Fuzzy_match.py

版本兼容性:

pandas version :: 1.1.5 ,
fuzzywuzzy version :: 1.1.0 ,
joblib version :: 0.18.0

Fuzzywuzzy 度量解釋: 鏈接文本

代碼輸出: 在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM