python匹配问题

news2024/11/18 9:49:48

脏数据匹配

一般数据建模步骤中,数据清洗耗时占比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
        # 判断左键值是否不为None
        if not ent[left_on]:
            continue
        for 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_key
                ent['right_key'] = right_key
                if uni[right_on] not in ent['Name List']:
                    ent['Name List'].append(uni[right_on])  # 创建name list字段方便日后遇到同样的名字可以直接进行匹配(这一步也可以不加)
                data[i] = ent
                break
    # 判断匹配后还剩多少未匹配对象
    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] = i

    for 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) * 100

    return (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.coloradmin.cn/o/1368097.html

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

相关文章

PyQT5实现图像处理应用(含Windows7下完整打包方案)

目录 1、任务概述2、环境安装2.1 创建虚拟环境2.2 安装依赖库 3、程序开发3.1 框架搭建3.2 读取图像3.3 图像处理 4、打包部署5、小结 1、任务概述 本篇博文将通过PyQT5来实现一个简单的图像处理应用,并完成打包部署。 本文开发平台:Windows10 64位系统…

【Vue3】2-6 : 计算属性与侦听器区别与原理(一)

本书目录:点击进入 一、计算属性 - computed:{} 1.1 目的 1.2 写法 代码 二、特征 2.1 调用时当属性调用 2.2 缓存 2.3 默认只读 2.4 可赋值:需要定义成对象,并写get,set方法 (类似于java) 三、原…

《More Effective C++》学习

条款1:仔细区别 pointers 和 references 引用应该被初始化,指针可以不被初始化。不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。指针与引用的另一个重要的不同是指针可以被重新赋值…

IDC MarketScape 低/无代码厂商评估:得帆信息被评为领导者

《IDC MarketScape:中国低代码/无代码开发平台2023年厂商评估 》报告正式发布。报告从战略与能力两大方向,在产品和功能、客户交付服务能力、营销和销售能力、伙伴与生态、商业战略模式等多个维度对国内低/无代码厂商进行全面评估。 得帆信息凭借战略与能力双项领先…

电子电器架构网络演化 —— 车载以太网TSN

电子电器架构网络演化 —— 车载以太网TSN 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消…

VBA中类的解读及应用第八讲:实现定时器功能的自定义类事件

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程,目前已经是第一版修订了。这套教程定位于最高级,是学完初级,中级后的教程。 类,是非常抽象的,更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -用户信息修改实现

锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

如何通过bat文件启动应用程序

说明:在windows上,任何应用程序都是通过.exe启动的。我们可以通过配置环境的方式,将应用程序的路径配置到环境变量path变量里,这样就可以使用cmd窗口,敲应用程序的名称来启动应用程序。 如下,可启动wps应用…

Vue-8、Vue事件处理

1、点击事件 <!DOCTYPE html> <html lang"en" xmlns:v-model"http://www.w3.org/1999/xhtml" xmlns:v-bind"http://www.w3.org/1999/xhtml"xmlns:v-on"http://www.w3.org/1999/xhtml"> <head><meta charset&quo…

Nginx location 配置 - Part 2

接上文 链接: Nginx 简介和入门 - part1 上文 我们简单地在 nginx 创建了3个虚拟主机&#xff0c; 虽然这个3个主机都是用占用80端口 但是我们可以用不同的域名来实现区分访问3台虚拟主机。 但是&#xff0c; 实际项目上&#xff0c; 我们更加多地会使用location 配置而不是…

Docker实战08|Docker管道及环境变量识别

上一篇文章中&#xff0c;讲解了如何通过Go语言实现对Docker Cgroup的资源限制 具体文章可见《Docker就应该这么学-07》 有需要的小伙伴可以回顾一下。 接下来本文会详细介绍一下Docker 管道及环境变量识别 管道及环境变量识别 获取代码 git clone https://gitee.com/mjr…

物理机部署三节点Kafka集群

一、部署Kafka集群 官方下载地址&#xff1a;http://kafka.apache.org/downloads.html上传安装包到102的/opt/software目录下 解压安装包到/opt/module/目录下&#xff0c;修改解压包名为kafka 修改config目录下的配置文件server.properties内容 #broker的全局唯一编号&#…

【漏洞复现】ActiveMQ文件上传漏洞(CVE-2016-3088)

Nx01 产品简介 Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件。ActiveMQ是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高可用、出色性能、可扩展、稳定和安全保障。 Nx02 漏洞描述 Ap…

excel统计分析——LSD多重比较

参考资料&#xff1a;生物统计学 一篇教你搞定显著性差异分析abcd字母标记法 LSD&#xff08;least significant difference&#xff0c;最小显著差数法&#xff09;是R. A. Fisher提出的&#xff0c;又称为Fisher LSD检验法&#xff0c;是最早用于检验各组均数间两两差异的方…

Unity | 渡鸦避难所-6 | 有限状态机控制角色行为逻辑

1 有限状态机简介 有限状态机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff09;&#xff0c;简称状态机&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型 在游戏开发中应用有限状态机&#xff…

NoSQL概述与Redis入门-redis安装与测试

一、Nosql概述 1、为什么使用Nosql 1、单机Mysql时代 90年代,一个网站的访问量一般不会太大&#xff0c;单个数据库完全够用。随着用户增多&#xff0c;网站出现以下问题 数据量增加到一定程度&#xff0c;单机数据库就放不下了数据的索引&#xff08;B Tree&#xff09;,一个…

38.深入MySQL

深入MySQL 索引 索引是关系型数据库中用来提升查询性能最为重要的手段。关系型数据库中的索引就像一本书的目录&#xff0c;我们可以想象一下&#xff0c;如果要从一本书中找出某个知识点&#xff0c;但是这本书没有目录&#xff0c;这将是意见多么可怕的事情&#xff01;我们…

【JaveWeb教程】(16) SpringBootWeb之 分层解耦 详细代码示例讲解

目录 SpringBootWeb请求响应3. 分层解耦3.1 三层架构3.1.1 介绍3.1.2 代码拆分 3.2 分层解耦3.2.1 耦合问题3.2.2 解耦思路 3.3 IOC&DI3.3.1 IOC&DI入门3.3.2 IOC详解3.3.2.1 bean的声明3.3.2.2 组件扫描 3.3.3 DI详解 SpringBootWeb请求响应 3. 分层解耦 3.1 三层架…

【UE Niagara学习笔记】01 - 浮动的蒲公英

目录 效果 步骤 一、创建材质 二、创建Niagara粒子 2.1 创建Niagara模板 2.2 通过用户参数设置粒子大小 2.3 设置数量、风速、透明度变化 2.4 设置粒子旋转 效果 步骤 一、创建材质 1. 在虚幻商城中把“Realistic Starter VFX Pack Vol 2”添加到项目中&#xff…

机器学习周刊 第4期:动手实战人工智能、计算机科学热门论文、免费的基于ChatGPT API的安卓端语音助手、每日数学、检索增强 (RAG) 生成技术综述

LLM开发者必读论文&#xff1a;检索增强&#xff08;RAG&#xff09;生成技术综述&#xff01; 目录&#xff1a; 1、动手实战人工智能 Hands-on Al2、huggingface的NLP、深度强化学习、语音课3、Awesome Jupyter4、计算机科学热门论文5、LLM开发者必读论文:检索增强 (RAG) 生…