公众号关注 “视学算法”

设为“星标”,第一时间知晓最新干货~

来源:Be_melting

https://blog.csdn.net/lys_828/article/details/106489371

【导语】:还在为日常工作中不同的数据集的字段进行匹配烦恼?今天跟大家分享FuzzyWuzzy一个简单易用的模糊字符串匹配工具包。让你多快好省的解决烦恼的匹配问题!

1. 前言

在处理数据的过程中,难免会遇到下面类似的场景,自己手里头获得的是简化版的数据字段,但是要比对的或者要合并的却是完整版的数据(有时候也会反过来)

最常见的一个例子就是:在进行地理可视化中,自己收集的数据只保留的缩写,比如北京,广西,新疆,西藏等,但是待匹配的字段数据却是北京市,广西壮族自治区,新疆维吾尔自治区,西藏自治区等,如下。因此就需要有没有一种方式可以很快速便捷的直接进行对应字段的匹配并将结果单独生成一列,就可以用到 FuzzyWuzzy 库。

2. FuzzyWuzzy库介绍

FuzzyWuzzy 是一个简单易用的模糊字符串匹配工具包。它依据 Levenshtein Distance 算法,计算两个序列之间的差异。

Levenshtein Distance算法,又叫 Edit Distance算法,是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。一般来说,编辑距离越小,两个串的相似度越大。

这里使用的是Anaconda下的jupyter notebook编程环境,因此在Anaconda的命令行中输入一下指令进行第三方库安装。

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple FuzzyWuzzy

2.1 fuzz模块

该模块下主要介绍四个函数(方法),分别为:简单匹配(Ratio)、非完全匹配(Partial Ratio)、忽略顺序匹配(Token Sort Ratio)和去重子集匹配(Token Set Ratio)

注意: 如果直接导入这个模块的话,系统会提示warning,当然这不代表报错,程序依旧可以运行(使用的默认算法,执行速度较慢),可以按照系统的提示安装python-Levenshtein库进行辅助,这有利于提高计算的速度。

2.1.1 简单匹配(Ratio)

简单的了解一下就行,这个不怎么精确,也不常用

fuzz.ratio("河南省", "河南省")
>>> 100
>
fuzz.ratio("河南", "河南省")
>>> 80

2.1.2 非完全匹配(Partial Ratio)

尽量使用非完全匹配,精度较高

fuzz.partial_ratio("河南省", "河南省")
>>> 100fuzz.partial_ratio("河南", "河南省")
>>> 100

2.1.3 忽略顺序匹配(Token Sort Ratio)

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

fuzz.ratio("西藏 自治区", "自治区 西藏")
>>> 50
fuzz.ratio('I love YOU','YOU LOVE I')
>>> 30fuzz.token_sort_ratio("西藏 自治区", "自治区 西藏")
>>> 100
fuzz.token_sort_ratio('I love YOU','YOU LOVE I')
>>> 100

2.1.4 去重子集匹配(Token Set Ratio)

相当于比对之前有一个集合去重的过程,注意最后两个,可理解为该方法是在token_sort_ratio方法的基础上添加了集合去重的功能,下面三个匹配的都是倒序

fuzz.ratio("西藏 西藏 自治区", "自治区 西藏")
>>> 40fuzz.token_sort_ratio("西藏 西藏 自治区", "自治区 西藏")
>>> 80fuzz.token_set_ratio("西藏 西藏 自治区", "自治区 西藏")
>>> 100

fuzz这几个ratio()函数(方法)最后得到的结果都是数字,如果需要获得匹配度最高的字符串结果,还需要依旧自己的数据类型选择不同的函数,然后再进行结果提取,如果但看文本数据的匹配程度使用这种方式是可以量化的,但是对于我们要提取匹配的结果来说就不是很方便了,因此就有了process模块。

2.2 process模块

用于处理备选答案有限的情况,返回模糊匹配的字符串和相似度。

2.2.1 extract提取多条数据

类似于爬虫中select,返回的是列表,其中会包含很多匹配的数据

choices = ["河南省", "郑州市", "湖北省", "武汉市"]
process.extract("郑州", choices, limit=2)
>>> [('郑州市', 90), ('河南省', 0)]
# extract之后的数据类型是列表,即使limit=1,最后还是列表,注意和下面extractOne的区别

2.2.2 extractOne提取一条数据

如果要提取匹配度最大的结果,可以使用extractOne,注意这里返回的是 元组 类型, 还有就是匹配度最大的结果不一定是我们想要的数据,可以通过下面的示例和两个实战应用体会一下

process.extractOne("郑州", choices)
>>> ('郑州市', 90)process.extractOne("北京", choices)
>>> ('湖北省', 45)

3. 实战应用

这里举两个实战应用的小例子,第一个是公司名称字段的模糊匹配,第二个是省市字段的模糊匹配

3.1 公司名称字段模糊匹配

数据及待匹配的数据样式如下:自己获取到的数据字段的名称很简洁,并不是公司的全称,因此需要进行两个字段的合并

直接将代码封装为函数,主要是为了方便日后的调用,这里参数设置的比较详细,执行结果如下:

3.1.1 参数讲解:

① 第一个参数df_1是自己获取的欲合并的左侧数据(这里是data变量);

② 第二个参数df_2是待匹配的欲合并的右侧数据(这里是company变量);

③ 第三个参数key1是df_1中要处理的字段名称(这里是data变量里的‘公司名称’字段)

④ 第四个参数key2是df_2中要匹配的字段名称(这里是company变量里的‘公司名称’字段)

⑤ 第五个参数threshold是设定提取结果匹配度的标准。注意这里就是对extractOne方法的完善,提取到的最大匹配度的结果并不一定是我们需要的,所以需要设定一个阈值来评判,这个值就为90,只有是大于等于90,这个匹配结果我们才可以接受

⑥ 第六个参数,默认参数就是只返回两个匹配成功的结果

⑦ 返回值:为df_1添加‘matches’字段后的新的DataFrame数据

3.1.2 核心代码讲解

第一部分代码如下,可以参考上面讲解process.extract方法,这里就是直接使用,所以返回的结果m就是列表中嵌套元祖的数据格式,样式为: [(‘郑州市’, 90), (‘河南省’, 0)],因此第一次写入到’matches’字段中的数据也就是这种格式

注意,注意: 元祖中的第一个是匹配成功的字符串,第二个就是设置的threshold参数比对的数字对象

s = df_2[key2].tolist()
m = df_1[key1].apply(lambda x: process.extract(x, s, limit=limit))
df_1['matches'] = m

第二部分的核心代码如下,有了上面的梳理,明确了‘matches’字段中的数据类型,然后就是进行数据的提取了,需要处理的部分有两点需要注意的:

① 提取匹配成功的字符串,并对阈值小于90的数据填充空值

② 最后把数据添加到‘matches’字段

m2 = df_1['matches'].apply(lambda x: [i[0] for i in x if i[1] >= threshold][0] if len([i[0] for i in x if i[1] >= threshold]) > 0 else '')
#要理解第一个‘matches’字段返回的数据类型是什么样子的,就不难理解这行代码了
#参考一下这个格式:[('郑州市', 90), ('河南省', 0)]
df_1['matches'] = m2return df_1

3.2 省份字段模糊匹配

自己的数据和待匹配的数据背景介绍中已经有图片显示了,上面也已经封装了模糊匹配的函数,这里直接调用上面的函数,输入相应的参数即可,代码以及执行结果如下:

数据处理完成,经过封装后的函数可以直接放在自己自定义的模块名文件下面,以后可以方便直接导入函数名即可,可以参考将自定义常用的一些函数封装成可以直接调用的模块方法。

4. 全部函数代码

#模糊匹配def fuzzy_merge(df_1, df_2, key1, key2, threshold=90, limit=2):""":param df_1: the left table to join:param df_2: the right table to join:param key1: key column of the left table:param key2: key column of the right table:param threshold: how close the matches should be to return a match, based on Levenshtein distance:param limit: the amount of matches that will get returned, these are sorted high to low:return: dataframe with boths keys and matches"""s = df_2[key2].tolist()m = df_1[key1].apply(lambda x: process.extract(x, s, limit=limit))    df_1['matches'] = mm2 = df_1['matches'].apply(lambda x: [i[0] for i in x if i[1] >= threshold][0] if len([i[0] for i in x if i[1] >= threshold]) > 0 else '')df_1['matches'] = m2return df_1from fuzzywuzzy import fuzz
from fuzzywuzzy import processdf = fuzzy_merge(data, company, '公司名称', '公司名称', threshold=90)
df

一个非常好用的 Python 魔法库相关推荐

  1. 肝!一个非常好用的 Python 魔法库

    来源:Be_melting https://blog.csdn.net/lys_828/article/details/106489371 [导语]:还在为日常工作中不同的数据集的字段进行匹配烦恼?今 ...

  2. python自带gui_一个极简易上手的 Python GUI 库

    原标题:一个极简易上手的 Python GUI 库 很多同学学了 Python 之后都想开发带界面的程序,也就是 GUI 应用.一般用的比较多的 GUI 库是 Tkinter(Python 自带)和 ...

  3. 一个超级牛X的Python可视化库,隔壁老奶奶都会用!

    今天给大家分享一个非常强大的可视化图形库. Python绘制各种各样的可视化图,比如折线图.饼状图,柱形图等等.大部分人可能会使用matplotlib或者pyecharts进行绘制 而我今天发现了一个 ...

  4. python orm库_周边生态贡献者+1,一个TDengine的Python ORM库—crown

    本文介绍了一个用于操作TDengine的 Python ORM库.本文的预期读者是,需要使用Python语言操作TDengine数据库的开发人员. 什么是ORM? ORM就是对象关系映射(Object ...

  5. 七个最流行的Python神经网络库

    https://www.toutiao.com/a6697243469124993550/ 由于具备包括各种各样的库.社区等在内的多种特性,Python是目前最广泛使用的语言之一.各种各样的库为神经网 ...

  6. python3库下载_下载安装Python第三方库的方法,最全方式,值得收藏

    一.利用Python中的pip进行第三方库的下载 首先我们要搞清楚Python中的pip是个什么东东?pip是一个安装和管理 Python包的工具,可以对python的包进行管理和升级等操作. 具体的 ...

  7. [转载] python常用库

    参考链接: Python–新一代语言 转载至:https://www.cnblogs.com/jiangchunsheng/p/9275881.html 今天我将介绍20个属于我常用工具的Python ...

  8. Python精选库大全,建议收藏留用!

    Python为啥这么火,这么多人学,就是因为简单好学,功能强大,整个社区非常活跃,资料很多.而且这语言涉及了方方面面,比如自动化测试,运维,爬虫,数据分析,机器学习,金融领域,后端开发,云计算,游戏开 ...

  9. python常用代码大全-Python常用库大全,看看有没有你需要的

    环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. v ...

最新文章

  1. Mavlink自定义协议
  2. 高压测试平台:高压包产生高电压基本测试参数
  3. 如何在VMware中安装Linux系统(带界面)~新手向
  4. linux 路由表设置 之 route 指令详解
  5. TDD容易被忽略的五大前提
  6. 信息学奥赛一本通 1094:与7无关的数 | OpenJudge NOI 1.5 39
  7. C++文件操作(打开、关闭、文件读取数据存入数组)
  8. UI培训之零基础如何自学UI设计?
  9. python语言之父丹尼斯里奇_C语言之父-丹尼斯里奇
  10. emos mysql_企业邮件部署详细步骤(EMOS)
  11. 20162327WJH实验五——数据结构综合应用
  12. ARC120F-Wine Thief(非F2)——序列化环
  13. 2023GPLT正赛 L2-4 寻宝图
  14. 高等数学Mathematica实验题——2.2 - 17.根号2的连分式展开(Expansion of square 2)
  15. Revit的二次开发带来的赢利点和后续故事
  16. 陶哲轩等人用编程方法,推翻了60年几何难题「周期性平铺猜想」
  17. mysql生产cdm文件_powerdesigner中CDM转化成PDM导出mysql脚本
  18. Unity中使用软连接快速切换平台
  19. Unity 骨骼动画 Anima2D
  20. 线性代数:特征值、特征多项式和特征向量

热门文章

  1. 【青少年编程】【二级】货运飞船
  2. 基于opencv的简单视频处理类示例
  3. 数字时代企业迎变局,如何让增长变简单?
  4. 基于微软开源深度学习算法,用 Python 实现图像和视频修复
  5. 蓝色起源载人火箭7月首飞,贝索斯即将实现儿时愿望
  6. 石锤!谷歌排名第一的编程语言,死磕这点,程序员都收益
  7. 张亚勤世界互联网大会谈AI:将变革传统行业,催生新业态
  8. 技术直播:程序员副业的修炼指南!(限免报名)
  9. 《评人工智能如何走向新阶段》后记(再续25)
  10. 西湖龙井也上链?是的,以后你喝什么茶我都知道!