使用python中的fuzzywuzzy庫進(jìn)行模糊匹配實例

fuzzywuzzy庫是Python中的模糊匹配庫,它依據(jù) Levenshtein Distance 算法 計算兩個序列之間的差異。

Levenshtein Distance 算法,又叫 Edit Distance 算法,是指兩個字符串之間,由一個轉(zhuǎn)成另一個所需的最少編輯操作次數(shù)。許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。一般來說,編輯距離越小,兩個串的相似度越大。

項目地址:https://github.com/seatgeek/fuzzywuzzy

安裝

使用 PIP 通過 PyPI 安裝

pip install fuzzywuzzy

用法

>>> from fuzzywuzzy import fuzz    >>> from fuzzywuzzy import process

簡單匹配(Simple Ratio)

>>> fuzz.ratio("this is a test", "this is a test!")        97

非完全匹配(Partial Ratio)

>>> fuzz.partial_ratio("this is a test", "this is a test!")        100

忽略順序匹配(Token Sort Ratio)

>>> fuzz.ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")        91    >>> fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")        100

去重子集匹配(Token Set Ratio)

>>> fuzz.token_sort_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear")        84    >>> fuzz.token_set_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear")        100

Process

用來返回模糊匹配的字符串和相似度,以下的例子就返回了分?jǐn)?shù)最高的兩個和一個字符串。

>>> choices = ["Atlanta Falcons", "New York Jets", "New York Giants", "Dallas Cowboys"]    >>> process.extract("new york jets", choices, limit=2)        [('New York Jets', 100), ('New York Giants', 78)]    >>> process.extractOne("cowboys", choices)        ("Dallas Cowboys", 90)

你可以傳入附加參數(shù)到 extractOne 方法來設(shè)置使用特定的匹配模式并返回和目標(biāo)匹配的字符串相似度最高的字符串。

>>> process.extractOne("System of a down - Hypnotize - Heroin", songs)
        ('/music/library/good/System of a Down/2005 - Hypnotize/01 - Attack.mp3', 86)   
>>> process.extractOne("System of a down - Hypnotize - Heroin", songs, scorer=fuzz.token_sort_ratio)
        ("/music/library/good/System of a Down/2005 - Hypnotize/10 - She's Like Heroin.mp3", 61

以下為實例部分:

需要將rawdata sheet中的信息與addcode中的信息進(jìn)行匹配,其中caname為大類,只有大類相同才可以進(jìn)行匹配。

sp_code為rawdata 表中的主鍵,因此我們直接將主鍵匹配到結(jié)果中

代碼如下:

from fuzzywuzzy import fuzz
from fuzzywuzzy import process
import pandas as pd

#將需要匹配的列表放入dataframe中并將需要匹配的信息拼起來
file_path=r"fuzzywuzzy test data.xlsx"
sp_rawdata=pd.read_excel(file_path,sheet_name='rawdata',index_col='sp_code')
sp_rawdata['text']=sp_rawdata['sp_webiste']+sp_rawdata['sp_channel']+sp_rawdata['sp_position']+sp_rawdata['sp_format']
tr_rawdata=pd.read_excel(file_path,sheet_name='addcode')
tr_rawdata['text']=tr_rawdata['tr_Website']+tr_rawdata['tr_Position_Channel']+tr_rawdata['tr_Format']

#獲取dataframe中cacode所有的去重后的值,并以列表的形式返回,即去重操作
sp_listtype=sp_rawdata['cacode'].unique()
tr_listtype=tr_rawdata['cacode'].unique()

scorelist=[]
rawlist=[]
#df = pd.DataFrame(columns = ["cacode", "tr_campaign_name", "tr_Website", "tr_Position_Channel", "tr_Format"])
for i in sp_listtype:
    # isin()接受一個列表,判斷該列中元素是否在列表中,再根據(jù)dataframe中的布爾索引進(jìn)行篩選,類似的篩選函數(shù)還有 str.contains()
    #在本例中,這個語句將cacode中屬于1,2,3的dataframe拆分成三個列表,從而匹配兩個dataframe時只會匹配cacode相同的信息
    sp_data = sp_rawdata[sp_rawdata['cacode'].isin([i])]
    tr_data = tr_rawdata[tr_rawdata['cacode'].isin([i])]
    #按行取dataframe中的值
    for row in  tr_data.itertuples():
        rawlist.append(row)
    for text in tr_data['text']:
        #忽略順序匹配并取出匹配分?jǐn)?shù)最高的值
        score = process.extractOne(str(text), sp_data['text'].astype(str), scorer=fuzz.token_sort_ratio)
        scorelist.append(score)

#轉(zhuǎn)換list為dataframe類型
scorecode=pd.DataFrame(scorelist)
df=pd.DataFrame(rawlist)
#修改轉(zhuǎn)變后的dataframe的字段名稱,注意這里0和1都不是字符串
scorecode=scorecode.rename(columns={0:'sp-text',1:'score',2:"add_sp_code"})
#兩個dataframe相連,axis: 需要合并鏈接的軸,0是行,1是列,這里按照列拼接
result=pd.concat([df,scorecode],axis=1)
result.to_excel(r" fuzzy mapping result.xlsx",index=False)

公眾號:Romi的雜貨鋪,更多的相關(guān)文章

源代碼及數(shù)據(jù)文件,結(jié)果文件可點(diǎn)擊https://github.com/smilecoc/smilecoc-fuzzywuzzy_test

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容