Python中的FuzzyWuzzy模块可以对两个字符串进行模糊匹配,而在有些场景下,我们需要在多个字段中进行一一对应的匹配,这时候我们可以拓展FuzzyWuz

285 篇文章 ¥59.90 ¥99.00
本文介绍了Python中的FuzzyWuzzy模块,用于字符串模糊匹配,并展示了如何扩展该模块实现多字段的一一对应匹配。通过将多个字段拼接成字符串,计算与查询信息的相似度得分,找到最佳匹配记录。

Python中的FuzzyWuzzy模块可以对两个字符串进行模糊匹配,而在有些场景下,我们需要在多个字段中进行一一对应的匹配,这时候我们可以拓展FuzzyWuzzy模块来实现这一需求。

一、FuzzyWuzzy模块简介

FuzzyWuzzy是一个基于Levenshtein距离的字符串匹配工具,它可以用来计算字符串的相似度。它支持以下四种模式:

1、Ratio模式:用于计算两个字符串之间的简单比率匹配得分。

2、Partial Ratio模式:用于计算两个字符串之间的部分比率匹配得分。

3、Token Sort Ratio模式:用于计算两个字符串之间的标记排序比率匹配得分。

4、Token Set Ratio模式:用于计算两个字符串之间的标记集比率匹配得分。

除此之外,它还提供了两个函数——process和extractBests,用于处理多个字符串之间的匹配问题。

二、多字段模糊匹配

在现实生活中,我们往往需要在多个字段(多列)中进行一一对应的匹配。例如,假设我们有一个包含身份证号、姓名、手机号、地址等信息的数据表,现在我们需要在该表中查找与某一个人信息最为匹配的记录。

针对这种情况,我们可以基于FuzzyWuzzy模块,自行编写一个函数来实现多个字段之间的模糊匹配。具体方法如下:

1、首先,我们需要对每一条记录中所有字段进行拼接,形成一个长字符串。

2、然后,我们将待查询人员的信息也进行同样的操作得到一个长字符串。

3、接着,我们使用FuzzyWuzzy模块计算这两个长字符串之间的相似度得分。

4、最后,我们将得分最高的记录返回即可。

Python中,进行字符串模糊匹配的核心库主要有**FuzzyWuzzy**、**TheFuzz**和**RapidFuzz**,它们均基于**Levenshtein距离**(编辑距离)算法来计算字符串之间的相似度 [ref_1][ref_2][ref_4]。下表对比了这三个库的主要特点: | 特性 | FuzzyWuzzy / TheFuzz | RapidFuzz | | :--- | :--- | :--- | | **核心算法** | Levenshtein Distance | Levenshtein Distance (优化实现) | | **主要接口** | `fuzz`, `process` 模块 | `fuzz`, `process`, `distance`, `utils` 模块 | | **性能** | 较慢(纯Python实现) | **极快**(C++实现,并行处理支持)[ref_2][ref_3] | | **维护状态** | FuzzyWuzzy已停止维护,TheFuzz是其活跃分支 | 活跃维护,功能更丰富 | | **推荐场景** | 学习、小规模数据 | **生产环境、大规模数据**[ref_3] | **RapidFuzz**因其卓越的性能和丰富的功能,是目前处理大规模模糊匹配任务的**首选推荐**[ref_2][ref_3]。 ### 核心相似度计算方法 这些库通过`fuzz`模块提供多种相似度计算策略,以应对不同匹配场景。 ```python # 安装库:pip install rapidfuzz from rapidfuzz import fuzz, process # 定义待比较字符串 str1 = "Apple iPhone 13 Pro Max" str2 = "iPhone 13 Pro" ``` 1. **简单比率 (Ratio)** 计算两个字符串整体编辑距离的相似度,适用于长度相近的完全匹配比较。 ```python similarity = fuzz.ratio(str1, str2) # 返回一个0-100的分数 print(f"简单比率相似度: {similarity}") # 输出可能较低,因为整体长度差异大 ``` 2. **部分比率 (Partial Ratio)** 将较短的字符串与较长字符串的所有子串进行比较,返回最佳匹配的相似度。非常适合检测一个字符串是否大致包含在另一个字符串中,例如搜索关键词[ref_1][ref_3]。 ```python similarity = fuzz.partial_ratio(str1, str2) print(f"部分比率相似度: {similarity}") # 输出会很高,因为str2完全包含在str1中 ``` 3. **令牌排序比率 (Token Sort Ratio)** 忽略单词顺序和大小写。先将字符串分词、转为小写、按字母排序后再进行`ratio`比较。适用于词序混乱但用词相同的场景,如用户自由输入[ref_1][ref_4]。 ```python str3 = "Max Pro 13 iPhone Apple" similarity = fuzz.token_sort_ratio(str1, str3) print(f"令牌排序比率相似度: {similarity}") # 输出会非常高,尽管词序不同 ``` 4. **令牌集合比率 (Token Set Ratio)** 更高级的策略,考虑交集和余集。它先找出两个字符串的公共词汇(交集),然后分别与原始字符串比较。对包含大量重复词或描述详略差异大的文本匹配效果极佳[ref_1][ref_5]。 ```python str4 = "Apple iPhone 13 Pro Max - 256GB - Blue" similarity = fuzz.token_set_ratio(str1, str4) print(f"令牌集合比率相似度: {similarity}") # 能有效忽略“256GB - Blue”这类额外信息 ``` ### 实战应用:从列表中查找最佳匹配 `process`模块的`extractOne`和`extract`函数,用于从一个候选列表中找出与查询字符串匹配的项[ref_2][ref_3]。 ```python # 候选列表 choices = [ "Apple iPhone 13 Pro Max", "Samsung Galaxy S22 Ultra", "Google Pixel 6 Pro", "iPhone 13", "iPhone 12 Pro Max" ] query = "iphone 13 pro" # 1. 查找单个最佳匹配 best_match = process.extractOne(query, choices, scorer=fuzz.token_sort_ratio) print(f"最佳匹配: {best_match[0]}, 相似度: {best_match[1]}") # 2. 查找多个匹配(例如相似度>80的) all_matches = process.extract(query, choices, scorer=fuzz.token_set_ratio, limit=None, score_cutoff=80) print("所有高相似度匹配:") for match, score, _ in all_matches: print(f" - {match}: {score}") ``` ### 高级功能与自定义(以RapidFuzz为例) RapidFuzz提供了更底层和灵活的接口。 1. **使用不同距离算法** ```python from rapidfuzz import distance # 计算标准Levenshtein距离(编辑次数) edit_distance = distance.Levenshtein.distance("kitten", "sitting") print(f"编辑距离: {edit_distance}") # 输出: 3 # 计算Jaro-Winkler相似度(对前缀相同更友好) jw_similarity = distance.JaroWinkler.similarity("MARTHA", "MARHTA") print(f"Jaro-Winkler相似度: {jw_similarity}") ``` 2. **多字段加权匹配** 在匹配包含多个属性(如品牌、型号、颜色)的商品时,可以为不同字段设置不同权重[ref_3]。 ```python from rapidfuzz import fuzz, utils import pandas as pd # 模拟数据 df_products = pd.DataFrame([ {"id": 1, "brand": "Apple", "model": "iPhone 13 Pro Max", "color": "Graphite"}, {"id": 2, "brand": "Samsung", "model": "Galaxy S22 Ultra", "color": "Burgundy"} ]) query_brand = "apple" query_model = "iphone 13 pro" def weighted_match(row): brand_score = fuzz.ratio(query_brand, row["brand"]) model_score = fuzz.token_sort_ratio(query_model, row["model"]) # 假设品牌权重0.4,型号权重0.6 weighted_score = 0.4 * brand_score + 0.6 * model_score return weighted_score df_products["match_score"] = df_products.apply(weighted_match, axis=1) print(df_products.sort_values("match_score", ascending=False)) ``` ### 应用场景 * **数据清洗与标准化**:将非标准输入(如“iphone13 pro”)映射到标准名称(如“Apple iPhone 13 Pro Max”)[ref_1][ref_4]。 * **搜索引擎与推荐系统**:提升搜索的模糊容错能力,或基于产品描述进行相似商品推荐[ref_4][ref_5]。 * **客户信息去重**:匹配拼写略有差异的客户姓名、地址等信息[ref_3]。 * **文本自动纠错**:为输入错误的单词或短语找到最可能的正确版本[ref_3]。 **总结建议**:对于学习和快速原型,TheFuzz(FuzzyWuzzy分支)简单易用。但对于任何涉及**性能敏感**或**大规模数据**的实际项目,应优先选择**RapidFuzz**,其高效的C++后端和丰富的API能显著提升处理速度并满足复杂匹配需求[ref_2][ref_3]。选择匹配策略时,`partial_ratio`适用于子串匹配,`token_sort_ratio`适用于忽略词序,`token_set_ratio`则对文本包含关系有更好的鲁棒性[ref_1][ref_5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值