python匹配问题

脏数据匹配

一般数据建模步骤中,数据清洗耗时占比80%以上,因为现实中接触到的数据相当脏,无法直接简单的用pandas的merge函数解决。下面以QS大学排名的匹配为例,简单介绍脏数据匹配中会遇到的问题和主要步骤。

1 问题描述

给定一个QS大学排名数据集,主要字段为大学名和排名,再给定一个带大学名称的本地数据集,我们需要根据QS表中的名字与我们已有的数据集中的大学名字进行匹配,然后将对应的QS排名添加到本地数据集中。QS数据集和本地数据集形式如下图:

image.png

image.png

数据匹配的过程中,可能出现以下几个问题需要处理。

  • 格式:比如是否加标点符号,名称顺序不同等
  • 语言:不同国家的学校语言可能不同
  • 别名:新旧名或多个名字、缩写等等

2 一般步骤

对于较为规整的数据,可以尝试直接用pandas的merge函数进行匹配,效率往往也较高。但merge函数只能解决规范化的问题,则建议使用json类型转化为列表和字典的组合形式,虽然降低了数据处理的速度,但提供了更灵活的匹配与修改操作。(ps 建议熟练掌握pandas的常用数据处理函数,了解其规范化的处理方式以及使用限制,才能很快判断是否能用标准库处理。)

原则上,匹配的过程遵循从精准匹配到模糊匹配的顺序。 因为已经匹配的数据将不参与后续的匹配,而模糊匹配可能会出现错误,且后续无法纠正该错误,所以应该在前面步骤实在无法匹配成功的情况下使用模糊匹配。

2.1 数据导入

# 将csv转为json再导入
qs = pd.read_csv('2024 QS World University Rankings 1.1 (For qs.com).csv')
data = pd.read_csv('data.csv')qs.to_json('QS_rank.json', orient='records')
data.to_json('data.json', orient='records')with open('QS_rank.json', 'r', encoding='utf-8') as f:qs = json.load(f)
with open('data.json', 'r', encoding='utf-8') as f:data = json.load(f)

2.2 匹配函数

left_on和right_on分别为左右合并键,func为判断是否匹配的函数,传入参数为要比较的两个字符串,返回是否匹配的bool值,以及两表对应匹配的字段,方便后续校对。

# 匹配函数
def merge(data, qs, left_on, right_on, func):for i in range(len(data)):ent = data[i]if left_on not in ent.keys():continue# 判断左键值是否不为Noneif not ent[left_on]:continuefor j in range(len(qs)):uni = qs[j]result = func(ent[left_on], uni[right_on])match, left_key, right_key = result[0], result[1], result[2]if match and ('QS rank' not in ent.keys()):ent['QS rank'] = uni['2024 RANK']ent['left_key'] = left_keyent['right_key'] = right_keyif uni[right_on] not in ent['Name List']:ent['Name List'].append(uni[right_on])  # 创建name list字段方便日后遇到同样的名字可以直接进行匹配(这一步也可以不加)data[i] = entbreak# 判断匹配后还剩多少未匹配对象print(pd.DataFrame(data)['QS rank'].isnull().sum())

2.3 匹配方式

按照从精准到不精准的匹配顺序,依次介绍传入匹配函数的func参数。(顺序可以根据具体情况判断,没有绝对的顺序)

2.3.1 完全相等

func_equal = lambda x, y : (x == y, x, y)
merge(data, qs, 'name', 'Institution Name', func_equal)

2.3.2 忽略大小写后相等

func_lower = lambda x, y : (x.lower() == y.lower(), x, y)
merge(data, qs, 'name', 'Institution Name', func_lower)

2.3.3 正则化匹配

将脏数据中没有实际意义的虚词删除可以进一步提高匹配数量,这一步可以用正则化来完成。根据数据集的具体情况,写对应的正则化pattern。需要注意的是,正则表达式来做替换时,需要注意替换的顺序,即先替换不容易满足的特例,再替换普遍容易满足的一般情况。

比如先用’ - ‘替换为’ ‘,再用’-‘替换为’ ‘,因为如果先替换后者则会使’ - '变为两个空格,而导致无法匹配上。

def pattern(string1, string2):patterns_need_delete = ['the ', '\'', '’', '‘', ',', 'universi[A-Za-z]* ', 'Üniversitesi '] patterns_need_replace = [' at ', ' in ', ' do ', ' de ', ' di ', ' of ', ' and ', ' & ', ' - ', '-', ' da ']string1, string2 = string1.lower(), string2.lower()for pa in patterns_need_replace:string1, string2 = re.sub(pa, ' ', string1, re.I).strip(), re.sub(pa, ' ', string2, re.I).strip()for pa in patterns_need_delete:string1, string2 = re.sub(pa, '', string1, re.I).strip(), re.sub(pa, '', string2, re.I).strip()# print(string1)# print(string2)set1, set2 = set(string1.split(' ')), set(string2.split(' '))return (set1.issubset(set2) or set2.issubset(set1), string1, string2)merge(data, qs, 'name', 'Institution Name', pattern)

2.3.4 编辑距离匹配

编辑距离函数计算两个字符串的相似度,100为完全匹配,0为完全不匹配,当编辑距离大于某个特定阈值则认为匹配。(这里取90)

# 编辑距离
def calculate_string_similarity(string1, string2, decimal_places=2):if not string1 or not string2:return (0, string1, string2)if string1 == string2:return (100, string1, string2)length1 = len(string1)length2 = len(string2)max_length = max(length1, length2)distance_matrix = [[0] * (length2 + 1) for _ in range(length1 + 1)]# 初始化编辑距离矩阵for i in range(length1 + 1):distance_matrix[i][0] = ifor j in range(length2 + 1):distance_matrix[0][j] = j# 填充编辑距离矩阵for i in range(1, length1 + 1):char1 = string1[i - 1]for j in range(1, length2 + 1):char2 = string2[j - 1]cost = 0 if char1 == char2 else 1# 计算编辑距离distance_matrix[i][j] = min(distance_matrix[i - 1][j] + 1,      # 删除操作distance_matrix[i][j - 1] + 1,      # 插入操作distance_matrix[i - 1][j - 1] + cost # 替换操作)# 计算相似度得分edit_distance = distance_matrix[length1][length2]similarity_score = (1 - edit_distance / max_length) * 100return (round(similarity_score, decimal_places) > 90, string1, string2)merge(data, qs, 'name', 'Institution Name', calculate_string_similarity)

2.3.5 包含匹配

a包含b,或b包含a则认为匹配。

func_contain = lambda x, y : ((x in y) or (y in x), x, y)
merge(data, qs, func_contain)

这一步需要注意误匹配问题,比如天津大学可能会与天津财经大学匹配。这个问题无法完全避免,可以先用精准匹配把天津大学完全匹配掉,然后在做剩下的匹配,但也无法完全避免误匹配,如果对精准度要求较高,则只能后续统一人工校对一遍。

2.3.6 忽略顺序匹配

有的字段所包含的字符完全一致但顺序不同,这时可以先将字符串按空格切分为列表,将列表转化为集合,比较集合是否相等。

def without_order(string1, string2):set1, set2 = set(string1.split(' ')), set(string2.split(' '))return (set1.issubset(set2) or set2.issubset(set1), string1, string2)
merge(data, qs, without_order)

前面所提到的步骤都可以结合使用,比如忽略顺序且相互包含。

2.3.7 人工匹配

每一步匹配结束后,可以查看尚未匹配的数据的情况,从而调整或生成新的匹配方法,对于最终仍未能匹配的个性化情况,则只能使用人工匹配与校对。可以根据维基百科为每个未匹配字段添加别名,然后据此重新匹配。

上述匹配方法可以扩展到很多其他脏数据匹配问题,类似的问题还有公司名称的匹配等,可作参考。

如果你对Python感兴趣,想要学习python,这里给大家分享一份Python全套学习资料,都是我自己学习时整理的,希望可以帮到你,一起加油!

😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

1️⃣零基础入门

① 学习路线

对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

② 路线对应学习视频

还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~
在这里插入图片描述

③练习题

每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
在这里插入图片描述

2️⃣国内外Python书籍、文档

① 文档和书籍资料

在这里插入图片描述

3️⃣Python工具包+项目源码合集

①Python工具包

学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
在这里插入图片描述

②Python实战案例

光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
在这里插入图片描述

③Python小游戏源码

如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
在这里插入图片描述

4️⃣Python面试题

我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述

上述所有资料 ⚡️ ,朋友们如果有需要的,可以扫描下方👇👇👇二维码免费领取🆓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/607606.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django全文搜索

Django ORM允许你执行简单的匹配操作,例如contains过滤器(或者不区分大小写的icontains)。 比如查询正文中包含django的文章 from blog.models import Post Post.objects.filter(body__containsframework) 但是如果希望执行复杂的搜索查询&…

Vue.js设计与实现阅读2

Vue.js设计与实现阅读-2 1、前言2、框架设计的核心要素2、1 提升用户体验2、2 控制代码体积2、3 Tree-Shaking2、4 特性开关2、5 错误处理 1、前言 上一篇我们了解到了 命令式和声明式的区别,前者关注过程,后者关注结果了解了虚拟dom存在的意义&#x…

WPF常用技巧-多线程处理

WPF支持单线程单元模型,该模型与在Windows窗体应用程序中使用的模型非常类似,具有以下几条原则: WPF元素具有线程关联性。创建WPF元素的线程拥有所创建的元素,其他线程不能直接与这些WPF元素进行交互。WPF对象都在类层次的某个位…

Java后端开发——SSM整合实验

文章目录 Java后端开发——SSM整合实验一、常用方式整合SSM框架二、纯注解方式整合SSM框架 Java后端开发——SSM整合实验 一、常用方式整合SSM框架 1.搭建数据库环境:MySQL数据库中创建一个名称为ssm的数据库,在该数据库中创建一个名称为tb_book的表 …

CAD数据转pcl可读数据

//-----------------------读取CAD模型------------------------vtkSmartPointer<vtkSTLReader> reader vtkSmartPointer<vtkSTLReader>::New();reader->SetFileName("data.stl");reader->Update();//----------------------转出到poly格式------…

如何顺滑使用华为云编译构建平台?

这两年平台构建服务需求越来越大&#xff0c;却一直苦于找不到一些指南&#xff0c; 这里特意写了一篇&#xff0c; 对在学习代码阶段和新手程序员朋友也蛮友好&#xff0c; 配置真的也不难&#xff0c; 也特别适合想尝试从0到1做个APP的朋友了。 以华为云的CodeArts Build为例…

CCF模拟题 202303-1田地丈量

问题描述 试题编号&#xff1a; 202303-1 试题名称&#xff1a; 田地丈量 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 问题描述&#xff1a; 西西艾弗岛上散落着 n 块田地。每块田地可视为平面直角坐标系下的一块矩形区域&#xff0c;由左下角坐标 (x1,y1) 和右…

OpenBLAS 的静态库命名分析 — — 以 x86_64 的静态库为例

在不同的机器上&#xff0c;生成的openblas生成的lib的名字可能是这样的&#xff1a; libopenblas_skylakexp-r0.3.26.dev.a libopenblas_skylakexp-r0.3.26.dev.so 也可能是这样的&#xff1a; liblapack_static_haswellp-r0.3.25.dev.a libopenblas_haswellp-r0.3.26.dev…

面试算法91:粉刷房子

题目 一排n幢房子要粉刷成红色、绿色和蓝色&#xff0c;不同房子被粉刷成不同颜色的成本不同。用一个n3的数组表示n幢房子分别用3种颜色粉刷的成本。要求任意相邻的两幢房子的颜色都不一样&#xff0c;请计算粉刷这n幢房子的最少成本。例如&#xff0c;粉刷3幢房子的成本分别为…

Linux-添加虚拟内存,不添加硬盘方式操作

在linux中&#xff0c;当物理内存mem不足时&#xff0c;就会使用虚拟内存(swap分区) 例如增加2G虚拟内存&#xff0c;操作如下: 1.查看内存大小 [rootlocalhost ~]# free -m 2.创建要作为swap分区的文件:增加1GB大小的交换分区&#xff0c;则命令写法如下&#xff0c;其中的cou…

1. 认识SPSS

使用的是IBM SPSS statistics 25&#xff0c;参考教材《统计分析与SPSS的应用》 一、安装和启动 具体安装过程是参考spss下载以及安装详细教程这篇文章&#xff0c;下载安装包然后按他的步骤获取用户许可证即可。 二、主要窗口 数据编辑器窗口data editor 是SPSS的主程序窗…

【C++之单例模式】

C之单例模式 前言介绍1、单例模式是什么&#xff1f;1.1 实现单例模式的三个要点1.2 单例模式分类 2. 懒汉式2.1 懒汉实现&#xff1a;基础方法2.2 懒汉实现&#xff1a;基于单锁2.3 懒汉实现&#xff1a;基于双重检测锁2.4 懒汉实现&#xff1a;基于双重检测锁和资源管理2.4.1…

ssm基于Vue的戏剧推广网站论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统戏剧推广信息管理难度大&#xff0c;容错率低&#xff0c…

代码随想录day23 二叉岁终章

669. 修剪二叉搜索树 题目 给定一个二叉搜索树&#xff0c;同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[L, R]中 (R>L) 。你可能需要改变树的根节点&#xff0c;所以结果应当返回修剪好的二叉搜索树的新的根节点。 思考 这题有个…

2024年中职网络安全——Windows操作系统渗透测试(Server2105)

Windows操作系统渗透测试 任务环境说明&#xff1a; 服务器场景&#xff1a;Server2105服务器场景操作系统&#xff1a;Windows&#xff08;版本不详&#xff09;&#xff08;封闭靶机&#xff09;需要环境加Q 目录 1.通过本地PC中渗透测试平台Kali对服务器场景进行系统服务…

Docker 部署后端项目自动化脚本

文章目录 开机自启动docker打包后端项目Dockerfile文件脚本文件使用 开机自启动docker systemctl enable dockersystemctl is-enabled docker打包后端项目 这里的项目位置是target同级目录 1.在项目下面新建一个bin目录 新建一个package.txt 写入下方代码后 后缀改为.bat ec…

配置git服务器

第一步&#xff1a; jdk环境配置 &#xff08;1&#xff09;搜索【高级系统设置】&#xff0c;选择【高级】选项卡&#xff0c;点【环境变量】 &#xff08;2&#xff09;在【系统变量】里面&#xff0c;点击【新建】 &#xff08;3&#xff09;添加JAVA_HOME环境变量JAVA_HO…

展开运算符(Spread Operator)

展开运算符&#xff08;Spread Operator&#xff09;是ES6中引入的一种语法&#xff0c;使用三个连续的点&#xff08;...&#xff09;表示。它可以在多种场合下使用&#xff0c;主要用途是“展开”数组或对象中的元素或属性。 使用展开运算符的几种常见情景&#xff1a; 在函…

小程序学习基础(页面加载)

打开首页&#xff0c;然后点击第一个按钮进去心得页面 进入心得页面以后 第一个模块是轮播图用的是swiper组件&#xff0c;然后就是四个按钮绑定点击事件&#xff0c;最后就是下拉刷新&#xff0c;下拉滚动&#xff0c;上拉加载。代码顺序wxml,js,wcss,json。 <!--pages/o…

【开源商城推荐-LGPL-3.0】ts-mall 聚惠星商城

dts-shop: 聚惠星商城 DTS-SHOP&#xff0c;基于 微信小程序 springboot vue 技术构建 &#xff0c;支持单店铺&#xff0c;多店铺入驻的商城平台。项目包含 微信小程序&#xff0c;管理后台。基于java后台语言&#xff0c;已功能闭环&#xff0c;且达到商用标准的一套项目体…