Python数据清洗实战:用RapidFuzz快速搞定模糊匹配(附常见坑点解析)

# Python数据清洗实战:用RapidFuzz快速搞定模糊匹配(附常见坑点解析) 处理脏数据,尤其是那些拼写不一致、格式混乱的文本字段,是数据分析师和ETL工程师日常工作中最头疼的环节之一。想象一下,你手头有一份客户名单,里面混杂着“Apple Inc.”、“apple inc”、“Apple公司”和“苹果公司”,如何将它们归一化为统一的实体?或者,一份产品目录里,“iPhone 13 Pro Max”被误写为“iPone 13 Pro Max”、“iphone13 promax”,又该如何自动修正?传统的精确匹配在这里完全失效,而正则表达式面对千变万化的错误也显得力不从心。 这正是模糊字符串匹配技术大显身手的地方。今天,我们不谈那些老生常谈的FuzzyWuzzy,而是聚焦于它的高性能继任者——**RapidFuzz**。这个基于C++的库,在速度上可以轻松超越前代百倍,同时提供了极其丰富的相似度算法。但工具强大,也意味着选择更多、潜在的“坑”也更多。直接调用`fuzz.ratio`就能解决所有问题吗?`token_set_ratio`和`partial_ratio`到底该在什么场景下用?如何与Pandas无缝集成,构建一个高效、可复用的数据清洗流水线? 本文将从一个真实的数据清洗场景出发,手把手带你构建一套基于RapidFuzz和Pandas的模糊匹配解决方案。我们会深入不同相似度算法的内核,解析它们各自的适用场景和陷阱,并提供可直接套用的代码模板。无论你是要清洗客户数据、合并多源产品信息,还是构建智能的搜索补全,这里都有你需要的实战经验。 ## 1. 环境搭建与核心概念速览 在开始实战之前,我们需要一个干净的工作环境。RapidFuzz的安装非常简单,但它有几个重要的“兄弟”库和版本细节需要注意。 首先,通过pip安装RapidFuzz。建议使用虚拟环境来管理依赖,避免包冲突。 ```bash # 创建并激活虚拟环境(以conda为例) conda create -n data-cleaning python=3.9 conda activate data-cleaning # 安装RapidFuzz及数据分析必备库 pip install rapidfuzz pandas numpy jupyter ``` 安装完成后,可以在Python中验证版本。RapidFuzz的版本迭代很快,不同版本间的API可能有细微差别。本文的代码基于3.x版本。 ```python import rapidfuzz import pandas as pd print(f"RapidFuzz版本: {rapidfuzz.__version__}") print(f"Pandas版本: {pd.__version__}") ``` 接下来,我们快速理解RapidFuzz的核心模块: * **`rapidfuzz.fuzz`**: 提供各种字符串相似度计算函数,如`ratio`, `partial_ratio`等。 * **`rapidfuzz.process`**: 提供在候选列表中搜索、提取最相似字符串的高级功能,这是数据清洗中最常用的模块。 * **`rapidfuzz.distance`**: 提供更底层的字符串距离计算,如Levenshtein距离、Damerau-Levenshtein距离等。 > **注意**: RapidFuzz默认**不会**对字符串进行任何预处理(如转小写、去除空格和标点)。这与它的前身FuzzyWuzzy不同。这意味着`"Apple"`和`"apple"`的相似度可能不是100%。这是一把双刃剑,它给了你更大的控制权,但也要求你在使用时心中有数。我们会在后面的章节详细讨论预处理策略。 ## 2. 五大核心算法深度解析与场景选择 RapidFuzz的`fuzz`模块提供了十几种相似度算法,初学者很容易眼花缭乱。实际上,大部分业务场景都可以由以下五个核心算法覆盖。理解它们的原理和差异,是避免误用的关键。 ### 2.1 Ratio:最基础的编辑距离相似度 `fuzz.ratio`计算的是基于Levenshtein距离的相似度。简单说,它衡量的是将一个字符串转换成另一个字符串所需的最少单字符编辑(插入、删除、替换)次数,然后将其归一化为0-100的分数。 ```python from rapidfuzz import fuzz str1 = "Apple Inc." str2 = "Apple Inc" str3 = "Apple Company" str4 = "apple inc." print(f"ratio('{str1}', '{str2}'): {fuzz.ratio(str1, str2)}") print(f"ratio('{str1}', '{str3}'): {fuzz.ratio(str1, str3)}") print(f"ratio('{str1}', '{str4}'): {fuzz.ratio(str1, str4)}") # 注意大小写和标点的影响 ``` **输出结果分析**: ``` ratio('Apple Inc.', 'Apple Inc'): 95 ratio('Apple Inc.', 'Apple Company'): 62 ratio('Apple Inc.', 'apple inc.'): 90 ``` * **适用场景**: 两个字符串长度相近,且错误主要是字符的错位、替换或少量增删。例如,纠正“Photoshp”为“Photoshop”。 * **主要坑点**: 1. **对顺序敏感**: `ratio("Apple Inc.", "Inc. Apple")`的分数会很低,因为顺序完全颠倒。 2. **对大小写和标点敏感**: 如上例所示,未预处理时大小写不同会扣分。 3. **不适用于子串匹配**: 短字符串是长字符串的一部分时,分数可能不理想。 ### 2.2 Partial Ratio:子串匹配的利器 `fuzz.partial_ratio`解决了`ratio`在子串匹配上的弱点。它寻找较短字符串在较长字符串中最匹配的子串,然后计算该子串的相似度。 ```python query = "Apple" choices = ["Apple Inc. California", "Pineapple Company", "Samsung Electronics"] for choice in choices: score = fuzz.partial_ratio(query, choice) print(f"partial_ratio('{query}', '{choice}'): {score}") ``` **输出**: ``` partial_ratio('Apple', 'Apple Inc. California'): 100 partial_ratio('Apple', 'Pineapple Company'): 80 # 因为包含'apple'子串 partial_ratio('Apple', 'Samsung Electronics'): 40 ``` * **适用场景**: 搜索和匹配场景。例如,在完整的公司地址中查找公司名,或用户输入一个简短关键词,在商品长标题中查找匹配。 * **主要坑点**: 可能产生“误伤”。比如用“苹果”去匹配“苹果手机”和“青苹果汁”,`partial_ratio`都可能给出高分,需要结合其他逻辑或阈值进行区分。 ### 2.3 Token Sort Ratio:无视单词顺序 这个算法先将字符串按空格分割成单词(token),对单词进行排序并重新拼接,然后再计算`ratio`。这完美解决了单词顺序不同的问题。 ```python str1 = "Apple Inc. California" str2 = "California, Apple Inc." str3 = "Inc. Apple California" print(f"ratio: {fuzz.ratio(str1, str2)}") print(f"token_sort_ratio: {fuzz.token_sort_ratio(str1, str2)}") print(f"\ntoken_sort_ratio('{str1}', '{str3}'): {fuzz.token_sort_ratio(str1, str3)}") ``` **输出**: ``` ratio: 52 token_sort_ratio: 100 token_sort_ratio('Apple Inc. California', 'Inc. Apple California'): 100 ``` * **适用场景**: 地址、产品描述等字段,其中单词的排列顺序可能不固定,但核心词汇集合相同。 * **主要坑点**: 对重复单词不敏感。`token_sort_ratio("apple apple", "apple")`的分数会很高,因为排序去重后本质是子集关系。如果需要处理重复信息,需留意。 ### 2.4 Token Set Ratio:处理单词集合的差异 这是功能更强大的一个算法。它先将字符串拆分为单词集合,然后比较两个集合的交集和差集。公式大致为:`score = ratio(交集 + 排序后的剩余部分A + 排序后的剩余部分B)`。它对重复单词不敏感,且能很好地处理一方包含另一方所有单词的情况。 ```python str1 = "Apple iPhone 13 Pro Max 256GB" # 商品全称 str2 = "iPhone 13 Pro Max" # 用户搜索词 str3 = "Max Pro 13 iPhone Apple" # 顺序混乱且完整 str4 = "iPhone 13 256GB" # 部分属性 scores = {} scores['token_sort'] = fuzz.token_sort_ratio(str1, str2) scores['token_set'] = fuzz.token_set_ratio(str1, str2) print("对比 token_sort_ratio 和 token_set_ratio:") for k, v in scores.items(): print(f" {k}: {v}") print(f"\ntoken_set_ratio('{str1}', '{str4}'): {fuzz.token_set_ratio(str1, str4)}") ``` * **适用场景**: **这是数据清洗中最常用、最稳健的算法之一**。特别适用于一方信息完整,另一方信息不全但核心关键词匹配的场景。比如,用产品型号匹配产品全称,用简写公司名匹配官方全称。 * **主要优势**: 对单词顺序、重复和部分缺失都有很好的鲁棒性。 ### 2.5 WRatio:加权综合算法 `fuzz.WRatio`是`ratio`的加权版本,它会根据字符串的长度等因素,智能地在`ratio`、`partial_ratio`、`token_sort_ratio`等算法之间进行选择和加权,试图给出一个更“聪明”的综合分数。当你不确定该选哪个算法时,可以先用`WRatio`试试水。 为了更直观地对比这五大算法,我们用一个表格总结: | 算法 | 核心原理 | 典型应用场景 | 优点 | 缺点/注意事项 | | :--- | :--- | :--- | :--- | :--- | | **`ratio`** | 基于Levenshtein编辑距离 | 拼写纠错、短文本精确匹配 | 原理直观,计算直接 | 对顺序、大小写敏感,不擅长子串匹配 | | **`partial_ratio`** | 寻找最佳匹配子串 | 搜索引擎、在长文本中查找关键词 | 擅长处理包含关系 | 可能匹配到不相关的子串(如“苹果”匹配“青苹果”) | | **`token_sort_ratio`** | 单词排序后比较 | 地址、描述等字段,单词顺序不固定 | 完全无视单词顺序 | 忽略单词重复次数 | | **`token_set_ratio`** | 比较单词集合的交并集 | **数据清洗、实体对齐**(强烈推荐) | 对顺序、重复、部分缺失均鲁棒 | 计算稍复杂,但通常值得 | | **`WRatio`** | 多种算法的加权组合 | 不确定最佳算法时的首选尝试 | 自动化程度高,适用性广 | 可解释性稍差,可能不是每个场景的最优解 | ## 3. 实战:构建Pandas数据清洗流水线 理论说得再多,不如一行代码。现在,我们模拟一个真实的数据清洗任务:有两张表,一张是脏乱的用户输入产品列表`df_dirty`,另一张是标准的产品主数据`df_master`。我们的目标是将`df_dirty`中的产品名与`df_master`对齐,并附上匹配度和标准ID。 首先,创建模拟数据: ```python import pandas as pd import numpy as np from rapidfuzz import process, fuzz # 标准产品主数据 df_master = pd.DataFrame({ 'product_id': [1001, 1002, 1003, 1004], 'product_name_clean': [ 'Apple iPhone 13 Pro Max 256GB', 'Samsung Galaxy S22 Ultra 512GB', 'Sony WH-1000XM4 Wireless Headphones', 'Logitech MX Master 3S Wireless Mouse' ] }) # 脏数据,包含各种错误 df_dirty = pd.DataFrame({ 'order_id': [1, 2, 3, 4, 5, 6], 'product_name_dirty': [ 'iphone 13 pro max 256', # 全小写,缺少GB 'Apple Iphone 13 Pro Max', # 拼写错误,缺少容量 'Samsung Galaxy S22 Ultra', # 缺少容量 'sony wh1000xm4 headphone', # 缺少连字符和`s`,单词单数 'Logitech MX Master 3 Mouse', # 型号错误 (3 vs 3S) 'Apple iphone 14' # 完全不匹配的型号 ] }) print("标准产品主数据:") print(df_master) print("\n待清洗的脏数据:") print(df_dirty) ``` 我们的清洗流水线将分为三步:**预处理**、**模糊匹配**、**后处理与校验**。 ### 3.1 第一步:设计预处理函数 预处理的目标是将字符串“归一化”,减少无关差异对匹配算法的干扰。常见的操作包括:转小写、去除多余空格、去除标点符号、统一缩写等。 ```python def preprocess_text(text): """ 文本预处理函数 """ if pd.isna(text): return "" # 1. 转换为小写 text = str(text).lower() # 2. 去除首尾空格 text = text.strip() # 3. 将多个空格替换为单个空格 import re text = re.sub(r'\s+', ' ', text) # 4. (可选) 移除常见标点,但注意可能破坏某些型号(如WH-1000XM4) # text = re.sub(r'[^\w\s]', '', text) # 5. 自定义替换规则(根据业务) replacements = { 'iphone': 'iphone', 'galaxy': 'galaxy', 'headphone': 'headphones', # 单复数统一 'mouse': 'mouse' } for wrong, right in replacements.items(): text = text.replace(wrong, right) return text # 应用预处理 df_dirty['product_name_processed'] = df_dirty['product_name_dirty'].apply(preprocess_text) df_master['product_name_processed'] = df_master['product_name_clean'].apply(preprocess_text) print("预处理后的脏数据:") print(df_dirty[['product_name_dirty', 'product_name_processed']]) ``` > **提示**: 预处理没有银弹。是否需要去除连字符“-”取决于你的业务:对于“WH-1000XM4”,去掉连字符可能有助于匹配“wh1000xm4”;但也可能意外破坏其他有意义的连接。最好在小样本上测试效果。 ### 3.2 第二步:执行模糊匹配 这是核心步骤。我们将使用`rapidfuzz.process.extract`或`extractOne`,为每个脏数据在标准库中寻找最佳匹配。 ```python def fuzzy_match_row(dirty_name, master_names, master_ids, scorer=fuzz.token_set_ratio, score_cutoff=80): """ 单行模糊匹配函数 :param dirty_name: 待匹配的脏字符串 :param master_names: 标准名称列表 :param master_ids: 对应的标准ID列表 :param scorer: 使用的相似度算法 :param score_cutoff: 最低接受分数阈值 :return: (匹配的产品ID, 匹配的标准名称, 相似度分数) 或 (None, None, 0) """ if not dirty_name: return None, None, 0 # 使用extractOne获取最佳匹配 result = process.extractOne( dirty_name, master_names, scorer=scorer, score_cutoff=score_cutoff # 低于此分数返回None ) if result: matched_name, score, index = result matched_id = master_ids[index] return matched_id, matched_name, score else: return None, None, 0 # 准备标准数据列表 master_names_list = df_master['product_name_processed'].tolist() master_ids_list = df_master['product_id'].tolist() # 对每一行脏数据应用匹配 matches = df_dirty['product_name_processed'].apply( lambda x: fuzzy_match_row(x, master_names_list, master_ids_list, scorer=fuzz.token_set_ratio, score_cutoff=70) ) # 将匹配结果拆分成多列 df_dirty[['matched_id', 'matched_name', 'match_score']] = pd.DataFrame( matches.tolist(), index=df_dirty.index ) print("\n匹配结果:") print(df_dirty[['order_id', 'product_name_dirty', 'matched_id', 'matched_name', 'match_score']]) ``` **代码解析**: 1. `process.extractOne`是核心,它返回最佳匹配项、分数及其在列表中的索引。 2. 我们设置了`score_cutoff=70`,低于70分的匹配将被视为“未匹配”。这个阈值需要根据业务敏感度调整(高风险业务调高,宽松场景调低)。 3. 这里选择了`token_set_ratio`作为打分器,因为它对信息缺失最鲁棒。 ### 3.3 第三步:结果分析与后处理 匹配完成后,我们必须人工或半自动地审查结果,特别是那些分数在阈值边缘的匹配。 ```python # 分析匹配质量分布 print("匹配分数分布:") print(df_dirty['match_score'].describe()) # 找出匹配不确定的项(例如分数在70-85之间) ambiguous_matches = df_dirty[(df_dirty['match_score'] >= 70) & (df_dirty['match_score'] < 85)] print(f"\n需要人工复核的匹配项(共{len(ambiguous_matches)}条):") for _, row in ambiguous_matches.iterrows(): print(f" 订单{row['order_id']}: '{row['product_name_dirty']}' -> '{row['matched_name']}' (分数: {row['match_score']:.1f})") # 找出未匹配的项 unmatched = df_dirty[df_dirty['matched_id'].isna()] print(f"\n未匹配的项(共{len(unmatched)}条):") print(unmatched[['order_id', 'product_name_dirty']]) ``` 对于未匹配和模糊匹配的项,我们可以: 1. **降低阈值**: 但可能引入错误。 2. **尝试其他算法**: 用`WRatio`或`partial_ratio`再跑一次,看结果是否更合理。 3. **人工审核**: 构建一个审核队列,这是保证数据质量的关键步骤。 4. **加入规则引擎**: 对于“Apple iphone 14”这种完全不在主数据中的情况,可以规则化地标记为“新产品待录入”。 ## 4. 高级技巧与性能优化 当数据量从几百条上升到几十万甚至百万条时,简单的循环匹配会变得极其缓慢。以下是几个提升性能的实战技巧。 ### 4.1 利用向量化与批处理 对于海量数据,避免在Python层进行逐行循环。RapidFuzz的`process.cdist`可以计算两个字符串列表之间的相似度矩阵。 ```python from rapidfuzz import process # 假设我们有大量脏数据和小量标准数据 dirty_list_large = df_dirty['product_name_processed'].tolist() * 1000 # 模拟6000条数据 master_list_small = df_master['product_name_processed'].tolist() # 4条标准数据 print(f"脏数据量: {len(dirty_list_large)}, 标准数据量: {len(master_list_small)}") # 使用cdist计算距离矩阵(这里用归一化距离,值越小越相似) from rapidfuzz.distance import Levenshtein import numpy as np # 注意:对于非常大的列表,内存可能爆炸。此例中矩阵大小为 6000 x 4 distances = process.cdist(dirty_list_large[:100], master_list_small, scorer=Levenshtein.normalized_distance) # 先测试100条 print(f"距离矩阵形状: {distances.shape}") # 找到每个脏数据对应的最相似标准数据的索引 best_match_indices = np.argmin(distances, axis=1) best_match_scores = 1 - distances[np.arange(len(distances)), best_match_indices] # 转换为相似度分数 ``` > **注意**: `cdist`会计算一个`M x N`的矩阵(M为脏数据条数,N为标准数据条数)。当N很大时(例如上万),内存消耗会非常惊人。因此,它更适用于**标准库较小,但待查数据量很大**的场景。 ### 4.2 构建索引与近似匹配 如果标准库也很大(例如十万级),逐条比较的复杂度是O(N*M),不可接受。此时需要考虑近似匹配或搜索索引。 * **方案一:使用`process.extract`的`limit`参数**: 即使标准库很大,`process.extract`内部也有优化。通过设置一个合理的`limit`(比如只返回前5个候选),可以大幅减少计算量。 ```python # 在大型master_list中,为每个dirty_name只寻找前5个候选 result = process.extract(dirty_name, large_master_list, scorer=fuzz.WRatio, limit=5) ``` * **方案二:预分组(Bucketing)**: 这是最有效的优化手段之一。根据字符串的某些特征(如首字母、长度范围、包含的关键词)将标准库预先分组。匹配时,只在与脏数据同组的“桶”内进行精细匹配,而不是全库扫描。 ```python # 示例:根据品牌关键词预分组 master_dict = {} for idx, name in enumerate(large_master_list): brand = None if 'apple' in name.lower(): brand = 'apple' elif 'samsung' in name.lower(): brand = 'samsung' # ... 其他品牌 else: brand = 'other' master_dict.setdefault(brand, []).append((idx, name)) # 匹配时,先提取脏数据的品牌,然后只在对应品牌的桶里搜索 ``` * **方案三:结合专业搜索引擎**: 对于超大规模(亿级)的模糊匹配需求,最终可能需要借助Elasticsearch、Milvus等专业的搜索引擎或向量数据库,它们内置了高效的近似最近邻搜索算法。 ### 4.3 处理多对多匹配与去重 有时,一个脏字符串可能对应多个标准实体(歧义),或者多个脏字符串指向同一个标准实体(去重)。 * **多对多匹配**: 使用`process.extract`并设置`limit`大于1,返回一个候选列表,由业务逻辑或人工决定最终选择。 ```python ambiguous_query = "苹果手机" candidates = process.extract(ambiguous_query, master_list, scorer=fuzz.token_set_ratio, limit=3) # candidates 可能是 [('Apple iPhone 13', 95), ('Apple iPhone 14', 90), ('华为手机', 60)] ``` * **记录去重**: `process.dedupe`函数可以直接对一个列表进行去重,保留相似度最高的一个作为代表。 ```python from rapidfuzz import process duplicate_list = ["Apple Inc.", "apple inc", "Apple Company", "Samsung Ltd.", "samsung ltd"] deduplicated = process.dedupe(duplicate_list, scorer=fuzz.token_set_ratio, threshold=90) print(list(deduplicated)) # 输出: ['Apple Inc.', 'Samsung Ltd.'] ``` ## 5. 避坑指南:从错误中学习的经验 我在多个数据清洗项目中踩过不少坑,这里分享几个最常见的,希望能帮你省下几个小时甚至几天的调试时间。 **坑点一:忽略预处理,导致匹配分数诡异** 这是新手最容易犯的错误。RapidFuzz默认不做预处理,所以`"Nike"`和`"nike"`的`ratio`分数只有80。**解决方案**:务必在匹配前实施一致的预处理流程,并在对比分数时,确保比较的是预处理后的字符串。 **坑点二:阈值设置一刀切** 用一个固定的阈值(比如85)过滤所有匹配结果。对于短字符串(如品牌名“LV”),轻微的编辑距离就会导致分数大幅波动;而对于长字符串(如产品全称),85分可能已经意味着匹配质量很高。**解决方案**:考虑使用动态阈值,或者根据字符串长度、业务重要性分级设置阈值。 **坑点三:算法选择不当导致系统性偏差** 例如,在匹配“北京大学”和“北京大學”(繁体)时,`ratio`分数会很低,因为字符完全不同。但实际上它们是同一个实体。**解决方案**:对于涉及多语言、简繁体、特殊字符的场景,需要在预处理阶段加入**字符规范化**(如使用`unicodedata.normalize`)或**翻译映射**。 **坑点四:性能瓶颈与内存溢出** 在Jupyter Notebook中直接对两个万级列表使用双层循环,导致内核卡死。**解决方案**: 1. 始终先在小样本(如100条)上测试流程和参数。 2. 对于大数据量,优先使用`process.cdist`(当标准库较小时)或**预分组**策略。 3. 使用`tqdm`库为循环添加进度条,方便监控和预估时间。 4. 考虑将任务拆分成批次(chunk)处理。 **坑点五:过度依赖自动化,缺乏人工审核** 模糊匹配不是魔法,总有边界情况。将分数在`[85, 95]`区间的匹配全部自动采纳,可能会引入难以察觉的错误,这些错误在后续分析中会被放大。**解决方案**:建立**人工审核流水线**。将所有低于某个高阈值(如95)或高于某个低阈值但被采纳的匹配,记录到一个审核表中,定期由熟悉业务的人员抽查。这能极大提升最终数据的可信度。 模糊匹配是数据清洗中一门结合了技术、业务经验和审慎态度的艺术。RapidFuzz提供了强大的武器,但如何用好它,取决于你对数据本身的理解和对算法特性的把握。从一个小而具体的场景开始,构建你的流水线,逐步迭代优化,你会发现处理脏数据不再是一件令人畏惧的苦差事。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

Python内容推荐

RapidFuzz:使用Levenshtein距离的Python快速模糊字符串匹配

RapidFuzz:使用Levenshtein距离的Python快速模糊字符串匹配

本文通过基准测试展示了FuzzyWuzzy和RapidFuzz两个库在执行模糊字符串匹配时的性能差异。测试涵盖了多个函数,如fuzz.ratio、fuzz.partial_ratio等,并将结果以可视

Python库 | rapidfuzz-0.13.2-cp27-cp27m-win_amd64.whl

Python库 | rapidfuzz-0.13.2-cp27-cp27m-win_amd64.whl

**数据清洗**:在数据预处理阶段,可以使用RapidFuzz来识别和纠正输入数据中的拼写错误或近似匹配。2.

Python库 | rapidfuzz-1.2.0-cp35-cp35m-win_amd64.whl

Python库 | rapidfuzz-1.2.0-cp35-cp35m-win_amd64.whl

总之,RapidFuzz是一个强大的Python库,用于字符串处理和模糊匹配,特别适合需要快速、高效处理大量文本数据的场景。

Python库 | rapidfuzz-1.0.0-cp38-cp38-manylinux2010_x86_64.whl

Python库 | rapidfuzz-1.0.0-cp38-cp38-manylinux2010_x86_64.whl

在Python开发中,尤其是在处理文本数据、搜索匹配、数据清洗等领域,RapidFuzz提供了一种快速且精确的方式来衡量两个字符串之间的相似性。1.

Python库 | rapidfuzz-1.3.0-cp35-cp35m-manylinux2010_x86_64.whl

Python库 | rapidfuzz-1.3.0-cp35-cp35m-manylinux2010_x86_64.whl

_x86_64.whl```安装完成后,我们就可以在Python代码中导入并使用RapidFuzz了:```pythonfrom rapidfuzz import fuzzprint(fuzz.ratio

Python库 | rapidfuzz-1.0.1-cp37-cp37m-macosx_10_9_x86_64.whl

Python库 | rapidfuzz-1.0.1-cp37-cp37m-macosx_10_9_x86_64.whl

`rapidfuzz`库的名称来源于“快速模糊”(Rapid Fuzzy),旨在提供快速且准确的模糊匹配功能。**一、核心功能**1.

Python库 | rapidfuzz-0.6.8-cp36-cp36m-manylinux2010_x86_64.whl

Python库 | rapidfuzz-0.6.8-cp36-cp36m-manylinux2010_x86_64.whl

《Python库深度解析:rapidfuzz-0.6.8-cp36-cp36m-manylinux2010_x86_64.whl》在Python编程世界中,丰富的第三方库是其魅力所在,它们极大地提升了开发效率和代码质量

Python库 | rapidfuzz-0.12.3.tar.gz

Python库 | rapidfuzz-0.12.3.tar.gz

这些函数可以帮助开发者快速找到与目标字符串相似的字符串,它们在一定程度上模糊匹配,适应各种应用场景,如用户输入校正、数据清洗、自动补全等。

Python库 | rapidfuzz-1.8.1.tar.gz

Python库 | rapidfuzz-1.8.1.tar.gz

资源分类:Python库所属语言:Python资源全名:rapidfuzz-1.8.1.tar.gz资源来源:官方安装方法:https://lanzao.blog.csdn.net/article/d

Python库 | rapidfuzz-1.7.1-cp27-cp27m-manylinux2010_i686.whl

Python库 | rapidfuzz-1.7.1-cp27-cp27m-manylinux2010_i686.whl

Python代码中导入并使用`rapidfuzz`库了:```pythonfrom rapidfuzz import fuzz, process# 示例:计算两个字符串的相似度similarity =

Python库 | rapidfuzz-1.9.0-cp310-cp310-win32.whl

Python库 | rapidfuzz-1.9.0-cp310-cp310-win32.whl

资源分类:Python库所属语言:Python使用前提:需要解压资源全名:rapidfuzz-1.9.0-cp310-cp310-win32.whl资源来源:官方安装方法:https://lanzao

Python库 | rapidfuzz-0.8.2.tar.gz

Python库 | rapidfuzz-0.8.2.tar.gz

资源分类:Python库所属语言:Python资源全名:rapidfuzz-0.8.2.tar.gz资源来源:官方安装方法:https://lanzao.blog.csdn.net/article/d

Python库 | rapidfuzz-1.4.0-cp38-cp38-win32.whl

Python库 | rapidfuzz-1.4.0-cp38-cp38-win32.whl

资源分类:Python库所属语言:Python资源全名:rapidfuzz-1.4.0-cp38-cp38-win32.whl资源来源:官方安装方法:https://lanzao.blog.csdn.

Python库 | rapidfuzz-0.13.0-cp36-cp36m-win_amd64.whl

Python库 | rapidfuzz-0.13.0-cp36-cp36m-win_amd64.whl

资源分类:Python库所属语言:Python使用前提:需要解压资源全名:rapidfuzz-0.13.0-cp36-cp36m-win_amd64.whl资源来源:官方安装方法:https://la

Python库 | rapidfuzz-0.8.1-cp36-cp36m-win_amd64.whl

Python库 | rapidfuzz-0.8.1-cp36-cp36m-win_amd64.whl

资源分类:Python库所属语言:Python使用前提:需要解压资源全名:rapidfuzz-0.8.1-cp36-cp36m-win_amd64.whl资源来源:官方安装方法:https://lan

Python库 | rapidfuzz-0.11.2-pp36-pypy36_pp73-win32.whl

Python库 | rapidfuzz-0.11.2-pp36-pypy36_pp73-win32.whl

资源分类:Python库所属语言:Python资源全名:rapidfuzz-0.11.2-pp36-pypy36_pp73-win32.whl资源来源:官方安装方法:https://lanzao.bl

Python库 | rapidfuzz-0.13.3-cp38-cp38-win32.whl

Python库 | rapidfuzz-0.13.3-cp38-cp38-win32.whl

资源分类:Python库所属语言:Python资源全名:rapidfuzz-0.13.3-cp38-cp38-win32.whl资源来源:官方安装方法:https://lanzao.blog.csdn

使用Levenshtein距离的Python快速模糊字符串匹配-C/C++开发

使用Levenshtein距离的Python快速模糊字符串匹配-C/C++开发

使用Levenshtein距离说明在Python和C ++中进行快速模糊字符串匹配•安装•使用•许可证说明RapidFuzz是一个快速字符串匹配库,用于使用Levenshtein距离说明在Python

Python库 | rapidfuzz-1.5.0-cp35-cp35m-manylinux2010_x86_64.whl

Python库 | rapidfuzz-1.5.0-cp35-cp35m-manylinux2010_x86_64.whl

资源分类:Python库所属语言:Python资源全名:rapidfuzz-1.5.0-cp35-cp35m-manylinux2010_x86_64.whl资源来源:官方安装方法:https://l

PyPI 官网下载 | rapidfuzz-0.4.0-cp37-cp37m-win_amd64.whl

PyPI 官网下载 | rapidfuzz-0.4.0-cp37-cp37m-win_amd64.whl

《PyPI官网下载:快速模糊匹配库rapidfuzz详解》在Python的开发环境中,我们经常需要处理字符串的相似度比较,例如用户输入的搜索关键词与数据库中的条目进行匹配。

最新推荐最新推荐

recommend-type

VS2022配置OpenCV[源码]

本文详细介绍了在Visual Studio 2022中永久配置OpenCV开发环境的步骤。首先,需要下载适合自己版本的OpenCV安装包,并添加相应的环境变量。接着,通过在VS2022中添加并配置项目属性表,实现OpenCV的永久配置。具体步骤包括添加包含目录、库目录以及附加依赖项等。此外,文章还介绍了如何在新的项目中快速完成配置,以及如何配置Release模式下的属性表。最后,通过一个简单的测试程序验证配置是否成功。整个过程清晰明了,适合开发者快速上手。
recommend-type

opencv4.7.0用VS2022编译的debug和release库

opencv4.7.0用VS2022编译的debug和release库
recommend-type

OpenCV源码阅读教程[项目代码]

本文介绍了如何在Windows10+VS2022+OpenCV4.7.0环境下查看OpenCV源码的方法。作者首先解释了为什么需要查看源码,例如为了重写函数或提升代码水平。接着提供了两种方法:对于未下载OpenCV的用户,建议从GitHub仓库下载源码;对于已下载OpenCV的用户,则详细说明了如何在安装文件夹中找到源码文件。文章还强调了正确查看源码的方式,即在modules文件夹内分模块查找src文件夹中的源码文件。
recommend-type

编译GPU加速OpenCV[可运行源码]

本文详细介绍了如何在Windows 10/11系统下,使用Visual Studio 2022和CMake工具编译支持GPU加速(CUDA + cuDNN)的OpenCV库。教程涵盖了环境准备、cuDNN安装验证、CMake GUI配置、Visual Studio编译、结果验证及常见问题解决等关键步骤。通过本教程,读者可以成功编译出支持CUDA/cuDNN的OpenCV库,从而在计算机视觉任务中利用GPU加速,提升DNN推理等任务的性能。
recommend-type

OpenCV4.8+CUDA编译教程[源码]

本文详细介绍了在Windows系统下使用CMake编译OpenCV4.8.0与CUDA结合的完整流程,包括准备工作、编译步骤及在VS2022中的配置方法。内容涵盖从下载所需文件、解决编译过程中的常见错误,到最终在项目中配置使用编译好的OpenCV库。此外,还提供了多个CUDA加速的OpenCV功能测试代码示例,如灰度转换、高斯模糊、角点检测、双边模糊、ORB特征匹配等,帮助开发者快速验证编译结果并应用于实际项目。
recommend-type

学生成绩管理系统C++课程设计与实践

资源摘要信息:"学生成绩信息管理系统-C++(1).doc" 1. 系统需求分析与设计 在进行学生成绩信息管理系统开发前,首先需要进行系统需求分析,这是确定系统开发目标与范围的过程。需求分析应包括数据需求和功能需求两个方面。 - 数据需求分析: - 学生成绩信息:需要收集学生的姓名、学号、课程成绩等数据。 - 数据类型和长度:明确每个数据项的数据类型(如字符串、整型等)和长度,例如学号可能是字符串类型且长度为一定值。 - 描述:详细描述每个数据项的意义,以确保系统能够准确处理。 - 功能需求分析: - 列出功能列表:用户界面应提供清晰的操作指引,列出所有可用功能。 - 查询学生成绩:系统应能通过学号或姓名查询学生的成绩信息。 - 增加学生成绩信息:允许用户添加未保存的学生成绩信息。 - 删除学生成绩信息:能够通过学号或姓名删除已经保存的成绩信息。 - 修改学生成绩信息:通过学号或姓名修改已有的成绩记录。 - 退出程序:提供安全退出程序的选项,并确保所有修改都已保存。 2. 系统设计 系统设计阶段主要完成内存数据结构设计、数据文件设计、代码设计、输入输出设计、用户界面设计和处理过程设计。 - 内存数据结构设计: - 使用链表结构组织内存中的数据,便于动态增删查改操作。 - 数据文件设计: - 选择文本文件存储数据,便于查看和编辑。 - 代码设计: - 根据功能需求,编写相应的函数和模块。 - 输入输出设计: - 设计简洁明了的输入输出提示信息和操作流程。 - 用户界面设计: - 用户界面应为字符界面,方便在命令行环境下使用。 - 处理过程设计: - 设计数据处理流程,确保每个操作都有明确的处理逻辑。 3. 系统实现与测试 实现阶段需要根据设计阶段的成果编写程序代码,并进行系统测试。 - 程序编写: - 完成系统设计中所有功能的程序代码编写。 - 系统测试: - 设计测试用例,通过测试用例上机测试系统。 - 记录测试方法和测试结果,确保系统稳定可靠。 4. 设计报告撰写 最后,根据系统开发的各个阶段,撰写详细的设计报告。 - 系统描述:包括问题说明、数据需求和功能需求。 - 系统设计:详细记录内存数据结构设计、数据文件设计、代码设计、输入/输出设计、用户界面设计、处理过程设计。 - 系统测试:包括测试用例描述、测试方法和测试结果。 - 设计特点、不足、收获和体会:反思整个开发过程,总结经验和教训。 时间安排: - 第19周(7月12日至7月16日)完成项目。 - 7月9日8:00到计算机学院实验中心(三楼)提交程序和课程设计报告。 指导教师和系主任(或责任教师)需要在文档上签名确认。 系统需求分析: - 使用表格记录系统需求分析的结果,包括数据项、数据类型、数据长度和描述。 - 分析数据项如学生成绩信息、状态器、链表节点等,确定其属性和行为。 以上就是文档中提到的学生成绩信息管理系统开发的关键知识点。开发此类系统需要熟练掌握C++编程基础,了解面向对象的程序设计思想,以及熟悉文件操作和链表等数据结构的应用。此外,良好的软件开发流程意识、测试意识和文档撰写能力也是必不可少的。
recommend-type

别再手动拖拽了!用Lumerical脚本批量创建FDTD仿真结构(附完整代码)

# 告别低效建模:Lumerical脚本自动化实战指南 在光子学仿真领域,时间就是科研生命线。当同行还在GUI界面里反复点击菜单时,你已经用脚本批量生成了20组参数化结构——这不是未来场景,而是每位FDTD用户都应该掌握的基础生产力革命。本文将彻底改变你与Lumerical的交互方式,从手动拖拽的农耕时代,跃迁到自动化建模的工业文明。 ## 1. 为何脚本建模是必然选择 2019年Nature Photonics的一项研究显示,科研工作者在仿真工具上平均浪费37%的时间在重复性操作上。对于需要参数扫描的纳米光学结构设计,这个数字可能更高。手动创建10个不同尺寸的纳米柱阵列意味着: -
recommend-type

Java邮件解析任务中,如何安全高效地提取HTML邮件内容并避免硬编码、资源泄漏和类型转换异常?

<think>我们被要求优化一段Java代码,该代码用于处理邮件(特别是来自特定发件人的构建通知邮件)。代码的主要问题包括: 1. 重复获取邮件内容:在检查MIME类型后,多次调用`msg[i].getContent()`,这可能导致性能问题或流关闭异常。 2. 类型转换问题:直接将邮件内容转换为`Multipart`而不进行类型检查,可能引发`ClassCastException`。 3. 代码结构问题:逻辑嵌套过深,可读性差,且存在重复代码(如插入邮件详情的操作在两个地方都有)。 4. 硬编码和魔法值:例如在解析HTML表格时使用了硬编码的索引(如list3.get(10)),这容易因邮件
recommend-type

RH公司应收账款管理优化策略研究

资源摘要信息:"本文针对RH公司的应收账款管理问题进行了深入研究,并提出了改进策略。文章首先分析了应收账款在企业管理中的重要性,指出其对于提高企业竞争力、扩大销售和充分利用生产能力的作用。然后,以RH公司为例,探讨了公司应收账款管理的现状,并识别出合同管理、客户信用调查等方面的不足。在此基础上,文章提出了一系列改善措施,包括完善信用政策、改进业务流程、加强信用调查和提高账款回收力度。特别强调了建立专门的应收账款回收部门和流程的重要性,并建议在实际应用过程中进行持续优化。同时,文章也意识到企业面临复杂多变的内外部环境,因此提出的策略需要根据具体情况调整和优化。 针对财务管理领域的专业学生和从业者,本文提供了一个关于应收账款管理问题的案例研究,具有实际指导意义。文章还探讨了信用管理和征信体系在应收账款管理中的作用,强调了它们对于提升企业信用风险控制和市场竞争能力的重要性。通过对比国内外企业在应收账款管理上的差异,文章总结了适合中国企业实际环境的应收账款管理方法和策略。" 根据提供的文件内容,以下是详细的知识点: 1. 应收账款管理的重要性:应收账款作为企业的一项重要资产,其有效管理关系到企业的现金流、财务健康以及市场竞争力。不良的应收账款管理会导致资金链断裂、坏账损失增加等问题,严重影响企业的正常运营和长远发展。 2. 应收账款的信用风险:在信用交易日益频繁的商业环境中,企业必须对客户信用进行评估,以便采取合理的信用政策,降低信用风险。 3. 合同管理的薄弱环节:合同是应收账款管理的法律基础,严格的合同管理能够保障企业权益,减少因合同问题导致的应收账款风险。 4. 客户信用调查:了解客户的信用状况对于预测和控制应收账款风险至关重要。企业需要建立有效的客户信用调查机制,识别和筛选信用良好的客户。 5. 应收账款回收策略:企业应建立有效的账款回收机制,包括定期的账款跟进、逾期账款的催收等。同时,建立专门的应收账款回收部门可以提升回收效率。 6. 应收账款管理流程优化:通过改进企业内部管理流程,如简化审批流程、提高工作效率等措施,能够提升应收账款的管理效率。 7. 应收账款管理策略的调整和优化:由于企业的内外部环境复杂多变,因此制定的管理策略需要根据实际情况进行动态调整和持续优化。 8. 信用管理和征信体系的作用:建立和完善企业内部信用管理体系和征信体系,有助于企业更好地控制信用风险,并在市场竞争中占据有利地位。 9. 对比国内外应收账款管理实践:通过研究国内外企业在应收账款管理上的不同做法和经验,可以借鉴先进的管理理念和方法,提升国内企业的应收账款管理水平。 综上所述,本文深入探讨了应收账款管理的多个方面,为RH公司乃至其他同类型企业提供了应收账款管理的改进方向和策略,对于财务管理专业的教育和实践都具有重要的参考价值。
recommend-type

新手别慌!用BingPi-M2开发板带你5分钟搞懂Tina Linux SDK目录结构

# 新手别慌!用BingPi-M2开发板带你5分钟搞懂Tina Linux SDK目录结构 第一次拿到BingPi-M2开发板时,面对Tina Linux SDK里密密麻麻的文件夹,我完全不知道从哪下手。就像走进一个陌生的大仓库,每个货架上都堆满了工具和零件,却找不到操作手册。这种困惑持续了整整两天,直到我意识到——理解目录结构比死记硬背每个文件更重要。 ## 1. 为什么SDK目录结构如此重要 想象你正在组装一台复杂的模型飞机。如果所有零件都混在一个箱子里,你需要花大量时间寻找每个螺丝和面板。但如果有分门别类的隔层,标注着"机身部件"、"电子设备"、"紧固件",组装效率会成倍提升。Ti