python中不規(guī)則字符串模糊匹配(fuzzywuzzy)
在日常的數(shù)據(jù)處理、文本分析或自然語(yǔ)言處理任務(wù)中,字符串匹配是一個(gè)常見需求。然而,由于拼寫錯(cuò)誤、格式差異、縮寫等原因,精確匹配(Exact Matching)往往無(wú)法滿足實(shí)際需求。此時(shí),模糊匹配(Fuzzy Matching)成為一種更靈活的選擇。
如下圖:2個(gè)excel中保存了一些公園的不同數(shù)據(jù),且只有公園名稱能唯一標(biāo)記一個(gè)公園。由于數(shù)據(jù)來(lái)源不同,公園的名稱是不完全相同的,且不規(guī)則,難以使用正則表達(dá)式等精確匹配,此時(shí)就可將進(jìn)行模糊匹配。

一、FuzzyWuzzy 簡(jiǎn)介
FuzzyWuzzy 由 SeatGeek 公司開發(fā)并開源,其核心算法基于 Levenshtein 距離(編輯距離),通過(guò)計(jì)算兩個(gè)字符串之間需要經(jīng)過(guò)多少次單字符編輯(增、刪、改)才能變得相同,來(lái)衡量它們的相似性。FuzzyWuzzy 進(jìn)一步優(yōu)化了這一過(guò)程,并提供了多種預(yù)定義的相似度計(jì)算方式,適用于不同場(chǎng)景。
主要特點(diǎn):
- 靈活性強(qiáng):支持部分匹配、忽略順序匹配、模糊分詞匹配等。
- 簡(jiǎn)單易用:通過(guò)封裝好的函數(shù)即可快速實(shí)現(xiàn)復(fù)雜匹配邏輯。
- 高效性:結(jié)合
python-Levenshtein庫(kù)可大幅提升計(jì)算速度。
二、核心功能與 API
FuzzyWuzzy 提供了多個(gè)相似度計(jì)算函數(shù),以下是常用的幾種方法:
簡(jiǎn)單匹配(Ratio)
- 計(jì)算兩個(gè)字符串的整體相似度,基于編輯距離。
from fuzzywuzzy import fuzz similarity = fuzz.ratio("apple", "appel") # 輸出 86部分匹配(Partial Ratio)
- 適合比較長(zhǎng)字符串與短字符串的匹配程度。例如,在長(zhǎng)文本中搜索子串。
fuzz.partial_ratio("apple pie", "apple") # 輸出 100
- 詞序無(wú)關(guān)匹配(Token Sort Ratio)
- 先對(duì)字符串分詞并按字母排序,再計(jì)算相似度。適合忽略單詞順序的場(chǎng)景。
fuzz.token_sort_ratio("apple orange", "orange apple") # 輸出 100
去重子集匹配(Token Set Ratio)
- 進(jìn)一步忽略重復(fù)詞,專注于共有詞匯的匹配。
fuzz.token_set_ratio("apple apple", "apple") # 輸出 100加權(quán)匹配(WRatio)
- 綜合多種策略,自動(dòng)選擇最佳匹配方式。
fuzz.WRatio("apple pie", "apple pi") # 輸出 95
三、高級(jí)應(yīng)用:從列表中提取最佳匹配
除了直接比較兩個(gè)字符串,F(xiàn)uzzyWuzzy 的 process 模塊支持從候選列表中快速找到與目標(biāo)最接近的匹配項(xiàng)。
from fuzzywuzzy import process
choices = ["apple", "banana", "orange", "grape"]
result = process.extractOne("appel", choices, scorer=fuzz.WRatio)
print(result) # 輸出 ('apple', 86)
參數(shù)說(shuō)明:
extractOne:返回列表中相似度最高的一個(gè)結(jié)果。scorer:指定相似度計(jì)算函數(shù)(默認(rèn)為WRatio)。- 支持設(shè)置分?jǐn)?shù)閾值(
score_cutoff),過(guò)濾低質(zhì)量匹配。
四、性能優(yōu)化
FuzzyWuzzy 的默認(rèn)實(shí)現(xiàn)可能較慢,尤其是在處理大規(guī)模數(shù)據(jù)時(shí)。通過(guò)以下方法可以提升性能:
安裝
python-Levenshtein庫(kù)
該庫(kù)用 C 語(yǔ)言實(shí)現(xiàn)了 Levenshtein 算法,能顯著加速計(jì)算:pip install python-Levenshtein
預(yù)處理數(shù)據(jù)
- 去除字符串中的空格、標(biāo)點(diǎn)符號(hào)。
- 統(tǒng)一轉(zhuǎn)換為小寫。
def preprocess(text): return text.lower().strip()限制匹配范圍
根據(jù)業(yè)務(wù)邏輯縮小候選列表的范圍(如按首字母分組)。
五、應(yīng)用場(chǎng)景
- 數(shù)據(jù)清洗
合并重復(fù)記錄(如用戶輸入的不同地址變體)。 - 搜索引擎
提升查詢糾錯(cuò)能力(如“New Yrok” → “New York”)。 - 自然語(yǔ)言處理
實(shí)體對(duì)齊、同義詞擴(kuò)展。 - 商業(yè)場(chǎng)景
商品名稱匹配、發(fā)票信息核對(duì)。
六、優(yōu)缺點(diǎn)分析
優(yōu)點(diǎn):
- 簡(jiǎn)單直觀,適合快速實(shí)現(xiàn)模糊匹配需求。
- 支持多種匹配策略,靈活應(yīng)對(duì)不同場(chǎng)景。
- 與 Python 生態(tài)集成良好(如 Pandas)。
缺點(diǎn):
- 對(duì)長(zhǎng)文本效果較差(計(jì)算復(fù)雜度高)。
- 默認(rèn)依賴
python-Levenshtein,可能需額外安裝。 - 不直接支持非英文文本(需結(jié)合分詞工具)。
替代方案
- difflib
Python 標(biāo)準(zhǔn)庫(kù)中的文本對(duì)比工具,功能較基礎(chǔ)。 - RapidFuzz
性能更優(yōu)的 FuzzyWuzzy 替代品,API 兼容。 - Jellyfish
支持更多字符串距離算法(如 Jaro-Winkler)。
七、完整代碼示例
import pandas as pd
from fuzzywuzzy import process
# 定義需要去除的詞
words_to_remove = ["NP", "&", "PRES", "N.M", "N.R."]
# 預(yù)處理函數(shù):去除特定詞
def preprocess_name(name):
for word in words_to_remove:
name = name.replace(word, "").strip() # 去除詞并去掉多余空格
return name
# 讀取Excel文件
df_all_parks = pd.read_excel("all.xlsx") # 替換為你的文件名
df_some_parks = pd.read_excel("結(jié)果.xlsx") # 替換為你的文件名
# 提取公園名稱列表
all_park_names = df_all_parks["英文名稱"].dropna().unique().tolist() # 替換"公園名稱"為實(shí)際列名
some_park_names = df_some_parks["Park Name"].dropna().unique().tolist()
# 模糊匹配并記錄結(jié)果
results = []
i = 0
for name in some_park_names:
# 預(yù)處理名稱:去除特定詞
cleaned_name = preprocess_name(name)
# 獲取最佳匹配(閾值可調(diào))
match, score = process.extractOne(cleaned_name, all_park_names, scorer=process.fuzz.token_sort_ratio)
if score >= 60: # 僅當(dāng)相似度≥60%時(shí)處理
# 找到在df_all_parks中匹配的行
matched_rows = df_all_parks[df_all_parks["英文名稱"] == match]
# 提取匹配行的distance值
distances = matched_rows["distance"].tolist() # 替換"distance"為實(shí)際列名
# 記錄結(jié)果
for i, distance in enumerate(distances):
results.append({
'序號(hào)': '',
"待匹配名稱": name, # 原始名稱
"預(yù)處理名稱": cleaned_name, # 預(yù)處理后的名稱
"匹配名稱": match,
"相似度": score,
"行號(hào)": matched_rows.index[i], # 記錄行號(hào)
"distance": distance # 添加distance列的值
})
else:
results.append({
'序號(hào)': '',
"待匹配名稱": name,
"預(yù)處理名稱": cleaned_name,
"匹配名稱": "無(wú)匹配",
"相似度": score,
"行號(hào)": [],
"distance": None # 無(wú)匹配時(shí)distance為空
})
# 轉(zhuǎn)換為DataFrame并保存結(jié)果
result_df = pd.DataFrame(results)
result_df.to_excel("模糊匹配結(jié)果.xlsx", index=False)
print("匹配完成!結(jié)果已保存到 '模糊匹配結(jié)果.xlsx'")
到此這篇關(guān)于python中不規(guī)則字符串模糊匹配(fuzzywuzzy)的文章就介紹到這了,更多相關(guān)python不規(guī)則字符串模糊匹配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Python實(shí)現(xiàn)音樂(lè)播放器的實(shí)現(xiàn)示例代碼
這篇文章主要介紹了如何利用Python編寫簡(jiǎn)易的音樂(lè)播放器,文中的示例代碼講解詳細(xì),具有一的參考價(jià)值,需要的小伙伴可以參考一下2022-04-04
在Python中字典根據(jù)多項(xiàng)規(guī)則排序的方法
今天小編就為大家分享一篇在Python中字典根據(jù)多項(xiàng)規(guī)則排序的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Python+OpenCV+圖片旋轉(zhuǎn)并用原底色填充新四角的例子
今天小編就為大家分享一篇Python+OpenCV+圖片旋轉(zhuǎn)并用原底色填充新四角的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
python爬取盤搜的有效鏈接實(shí)現(xiàn)代碼
這篇文章主要介紹了python爬取盤搜的有效鏈接,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07
Python數(shù)據(jù)分析23種Pandas核心操作方法總結(jié)
在本文中,作者從基本數(shù)據(jù)集讀寫、數(shù)據(jù)處理和?DataFrame?操作三個(gè)角度展示了?23?個(gè)?Pandas?核心方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
50行Python代碼獲取高考志愿信息的實(shí)現(xiàn)方法
這篇文章主要介紹了50行Python代碼獲取高考志愿信息的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07

