Python 库- FuzzyWuzzy使用介绍

1. FuzzyWuzzy简介

FuzzyWuzzy是一个 Python 库,旨在提供模糊字符串匹配的功能。它能够比较两个字符串之间的相似度,即使它们在拼写或格式上略有不同。通过使用各种算法和方法,如基于字符、基于单词的匹配,以及部分匹配和排序匹配等技术,FuzzyWuzzy 能够有效地处理文本数据中的拼写错误、近义词和重复项。这使得它在数据清洗、搜索功能、自动完成和信息抽取等场景中非常实用。FuzzyWuzzy 提供了简单易用的 API,使得开发者可以轻松地将其集成到自己的项目中,并快速实现字符串匹配和相似度比较的功能。

​ FuzzyWuzzy对大型数据集性能比较低,一般都会结合使用 Pandas、numpy 等数据科学模块实现模糊匹配,可以更方便地处理大量数据和进行数据分析。Pandas 提供了灵活的数据结构和功能,可以帮助简化模糊匹配的过程,并且可以轻松地与其他数据处理和分析工具集成。

  • 相似功能库对比
核心特点使用方法对比分析最大优势
FuzzyWuzzy- 提供模糊字符串匹配功能 - 简单易用的 API - 多种匹配方法- fuzz.ratio - fuzz.partial_ratio - fuzz.token_sort_ratio - fuzz.token_set_ratio- 提供了多种方法来处理模糊匹配问题 - 简单易用,适合快速开发 - 速度可能较慢,对于大型数据集可能不够高效,可安装python-Levenshtein库进行辅助提速灵活的匹配方法
difflib- Python 标准库中的模块 - 提供序列比较和相似度计算功能- SequenceMatcher- 包含在 Python 标准库中,无需额外安装 - 功能相对较少,只提供了一种比较方法包含在 Python 标准库中
rapidfuzz- 快速、高效的字符串匹配库- fuzz.ratio - fuzz.partial_ratio - fuzz.token_sort_ratio - fuzz.token_set_ratio- 速度更快,性能更好 - 提供了与 FuzzyWuzzy 类似的功能,但速度更快高效的字符串匹配
pyspellchecker- 检查和纠正拼写错误的 Python 库- SpellChecker- 主要用于拼写检查和纠正,不是专注于模糊字符串匹配 - 可以用于纠正用户输入中的拼写错误拼写检查和纠正功能
textdistance- 计算文本之间距离的 Python 库- 各种距离度量方法- 提供了一些字符串相似度度量方法,如 Levenshtein 距离、Jaro-Winkler 距离等 - 功能丰富,适合进行各种文本距离计算 - 与 FuzzyWuzzy 相比,可能更适合需要特定距离度量方法的场景,但可能不如 FuzzyWuzzy 灵活和简单提供了多种字符串相似度度量方法

2. 安装 FuzzyWuzzy 库

pip install fuzzywuzzy

# 清华源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple FuzzyWuzzy

3. FuzzyWuzzy使用方法

3-1. FuzzyWuzzy - fuzz

主要函数作用示例
ratio计算完整匹配相似度比较完全相似度,不考虑单词的顺序或重复。
partial_ratio计算部分匹配相似度不考虑单词的顺序,只匹配部分内容,可以找出两个字符串中的相似部分。
token_sort_ratio计算排序后相似度对两个字符串中的单词进行排序,然后计算排序后的字符串的相似度。不考虑单词的顺序。
token_set_ratio计算集合相似度将两个字符串视为单词集合,不考虑单词的顺序和重复。可以处理单词的添加或删除。
3-1-1. ratio
  • 简单匹配

比较两个字符串的相似程度,返回一个介于 0 和 100 之间的相似度分数。分数越高表示字符串越相似。

from fuzzywuzzy import fuzz

similarity_01 = fuzz.ratio("wangting", "wangtinggg")
print(similarity_01)
# Output : 89

similarity_02 = fuzz.ratio("wangting_666", "wangting")
print(similarity_02)
# Output : 80

similarity_03 = fuzz.ratio("wangting_666", "wangting_666")
print(similarity_03)
# Output : 100

similarity_04 = fuzz.ratio("ngtin", "wangting_666")
print(similarity_04)
# Output : 67

大部分环境运行代码会提示如下提示

UserWarning: Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning
  warnings.warn('Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning
  
# 安装levenshtein包即可
pip install python-levenshtein

python-Levenshtein 是一个用于计算编辑距离的强大而高效的库,适用于各种需要字符串相似度计算的场景
3-1-2. partial_ratio
  • 非完全匹配

比较两个字符串的相似度,不考虑字符串的顺序,而是仅匹配部分。返回一个介于 0 和 100 之间的相似度分数。

from fuzzywuzzy import fuzz

similarity_01 = fuzz.partial_ratio("wangting", "wangtinggg")
print(similarity_01)
# Output : 100

similarity_02 = fuzz.partial_ratio("wangting_666", "wangting")
print(similarity_02)
# Output : 100

similarity_03 = fuzz.partial_ratio("wangting_666", "wangting_666")
print(similarity_03)
# Output : 100

similarity_04 = fuzz.partial_ratio("angtin", "wangting_666")
print(similarity_04)
# Output : 100

similarity_05 = fuzz.partial_ratio("1wangting_666", "2wangting_777")
print(similarity_05)
# Output : 69

可以看出来相比ratiopartial_ratio是只要字符串能完全匹配上,即使有多余字符,依旧给出100%的相似度

3-1-3. token_sort_ratio
  • 忽略顺序匹配

先对两个字符串中的单词进行排序,然后计算排序后的字符串的相似度。它不考虑单词的顺序。

以 空格 为分隔符,小写 化所有字母,无视空格外的其它标点符号

from fuzzywuzzy import fuzz

similarity_01 = fuzz.token_sort_ratio("all cat dog", "dog cat bug")
print(similarity_01)
# Output : 73

similarity_02 = fuzz.token_sort_ratio("all bug cat", "dog cat bug all")
print(similarity_02)
# Output : 85

similarity_03 = fuzz.token_sort_ratio("all bug cat dog", "dog cat bug all")
print(similarity_03)
# Output : 100

similarity_04 = fuzz.token_sort_ratio("all dog dog dog ", "dog dog all")
print(similarity_04)
# Output : 85
3-1-4. token_set_ratio
  • 去重子集匹配

计算两个字符串的相似度,将它们视为单词集合。它不考虑单词的顺序和重复。process: 在一组字符串中查找与给定字符串最相似的字符串,并返回包含匹配项及其相似度的列表。

可理解为该方法是在token_sort_ratio方法的基础上添加了集合去重的功能

similarity_01 = fuzz.token_set_ratio("all cat dog", "dog cat bug")
print(similarity_01)
# Output : 78

similarity_02 = fuzz.token_set_ratio("all bug cat", "dog cat bug all")
print(similarity_02)
# Output : 100

similarity_03 = fuzz.token_set_ratio("all bug cat dog", "dog cat bug all")
print(similarity_03)
# Output : 100

similarity_04 = fuzz.token_set_ratio("all dog dog dog ", "dog dog all")
print(similarity_04)
# Output : 100

3-2. FuzzyWuzzy - process

3-2-1. extract

在一组字符串中查找与给定字符串最相似的字符串,并返回包含匹配项及其相似度的列表

from fuzzywuzzy import process

query = "apple"
choices = ["apple", "banana", "orange", "grape"]

matches = process.extract(query, choices)
print(matches)

# Output : [('apple', 100), ('grape', 60), ('orange', 36), ('banana', 18)]
3-2-2. extractOne

从一组选择中提取与给定查询字符串最相似的单个项,并返回包含匹配项及其相似度的元组。

from fuzzywuzzy import process

query = "apple"
choices = ["app", "apple", "banana", "orange", "grape"]

best_match = process.extractOne(query, choices)
print(best_match)

# Output : ('apple', 100)
3-2-3. dedupe

去除重复项并保留最相似的项。

from fuzzywuzzy import process

choices = ["app", "apple", "appel", "banana", "orange", "grape", "grapefruit"]

deduped_choices = process.dedupe(choices)
print(deduped_choices)

# Output : dict_keys(['appel', 'banana', 'orange', 'grape', 'grapefruit'])
3-2-4. extractBests

从一组选择中提取最相似的项,并返回包含匹配项及其相似度的列表,可指定返回的项数。

from fuzzywuzzy import process

query = "apple"
choices = ["app", "apple", "appel", "banana", "orange", "grape", "grapefruit"]

best_matches_80 = process.extractBests(query, choices, score_cutoff=80)
best_matches_95 = process.extractBests(query, choices, score_cutoff=95)
print(best_matches_80)
print(best_matches_95)

# Output : [('apple', 100), ('app', 90), ('appel', 80)]
# Output : [('apple', 100)]

3-3. 业务应用场景示例

3-3-1. 工商数据处理示例

根据公司名称进行模糊匹配,找出相似的公司名称。

from fuzzywuzzy import process

# 工商数据集
company_names = ["小米集团", "药明康德", "华谊兄弟", "长电科技", "Amazon.com Inc."]

# 模糊匹配公司名称
query = "小米"
matches = process.extract(query, company_names, limit=1)
print(matches)

# Output : [('小米集团', 90)]
3-3-2. 舆情数据处理示例

根据新闻标题或内容,找出与给定关键词相似的新闻。

from fuzzywuzzy import process

# 舆情标题集
news_titles = ["《今天大盘走的太完美了,明天继续上涨》", "《普涨行情,近期有望继续延续》",
               "《今天的主线依旧是人工智能》", "《三大指数全天冲高回来,难掩下跌趋势》", "《上涨行情需要足够耐心静待花开》"]

# 匹配与关键词相似的新闻标题
keyword = "上涨"
matches = process.extract(keyword, news_titles)
print(matches)

# Output : [('《上涨行情需要足够耐心静待花开》', 90), ('《今天大盘走的太完美了,明天继续上涨》', 60), ('《普涨行情,近期有望继续延续》', 45), ('《今天的主线依旧是人工智能》', 0), ('《三大指数全天冲高回来,难掩下跌趋势》', 0)]
3-3-3. 处理用户输入示例

推测纠正用户输入的内容错误给出相近选项

from fuzzywuzzy import process

# DB_list
choices = ["MySQL", "Oracle", "SqlServer", "SQLite", "Redis", "MongoDB", "Neo4J", "HBase", "CouchDB"]

# 用户输入
user_input = "mongo"

# 查找最佳匹配
best_match = process.extractOne(user_input, choices)
print("是否想选择:" + str(best_match))


# Output : 是否想选择:('MongoDB', 83)
3-3-4. 结合Pandas模块示例

假设我们有一个包含公司名称的数据框,我们想要对其中的公司名称进行模糊匹配。我们可以使用 Pandas 和 FuzzyWuzzy 库来实现

pip install pandas

import pandas as pd
from fuzzywuzzy import process

# 创建一个包含公司名称的数据框
data = {'银行清单': ['北京银行', '上海银行', '招商银行', '农业银行', '南京银行']}
df = pd.DataFrame(data)

# 定义要匹配的目标字符串
query = '南京'

# 使用 Pandas 的 apply 方法和 FuzzyWuzzy 的 extractOne 方法进行模糊匹配
df['相似匹配'] = df['银行清单'].apply(lambda x: process.extractOne(query, [x])[1])

print(df)

# Output : 
"""
   银行清单  相似匹配分
0  北京银行    45
1  上海银行     0
2  招商银行     0
3  农业银行     0
4  南京银行    90
"""
Logo

科技之力与好奇之心,共建有温度的智能世界

更多推荐