当前位置: 首页 > news >正文

python merge on多个条件_Python数据核对系列之2—power query VS pandas

提示:本文略长,干货满满上一篇文章我们整体梳理了我核对两个表数据,从excel query模式一版版过渡到python多线程多进程读取数据库数据后完成核对并输出结果到数据库表中的整个版本迭代过程。从本篇开始,我们挨个梳理讲解下,在整个过程中我的实际操作,遇到的各种坑,以及找到的解决方案。

Excel power query两表核对

66e6496a89b28a1687e23e9b20901ff6.png

利用query进行核对使用的是query里面的合并查询,其实也就是sql当中的左连接、右连接、全外连接。可以通过设定的连接字段来完成两表的合并。我们从数据-新建查询-从文件里选择从工作簿或者从csv。然后加载我们的源文件。

3ce2a860af6536f97231fc4ed26d6e3a.png

在选择csv文件加载的时候,有时候会因为原始数据的某个字段里包含换行符而导致加载完的数据会出现错行问题,导致你的数据格式设置会报错。这个问题的解决方案我们之前已经发过了,大家再遇到的话可以再查看一下。power query加载csv错行?

原始数据加载完后,我们选择query的主页里的组合中的合并查询

85233668ff28aee8e5039dad793e4c52.png

合并查询里有个合并查询、将查询合并为新查询

9f1cc498f678a550b9f43a412446ffac.png

点击合并查询后,弹出合并设置窗口,选择两个原始表的查询,并点选连接字段。

f2e438a33ca24dd91f207699457d1f85.png

如果是多个连接字段的话,需要按住ctrl点击字段,效果会如下图所示

1a25557399d2c82b38646a3b0f288463.png

选择完连接的字段之后,我们需要设置他们的连接种类。共有6种连接设置。上面的解释也很清楚明白。

1d88735faa8ed46a5ebb59803f806b2f.png

选择连接方式之后,它会显示连接的匹配行数。

861d836b2aed6c05f1b6f8aa5296850e.png

两表连接完成之后,关联的数据会存储在一新的列里

78303e17f56d41fd53d36af469278136.png

点击这个table,它会显示跟当前数据关联的数据明细

如果关联的数据有多条如下图所示

58e65870559b2beec98687742928e11e.png

单条数据如下图所示

c655117a508a63b5fa3fd4f42d1e5e8d.png

点击这个合并列的右上角的符号8afb974b863cdd858a36af969ff64b8d.png,可以对数据进行展开。

448c7807486cb568cb8b694664828963.png

展开时可以选择展开(明细数据),聚合(汇总数据),还可以选择原始列名作为展开后的列名的前缀。

展开之后我们就可以针对要核对的列进行值比对了。

在这里我们引申一下,简单介绍下query函数

点击主页菜单里高级编辑器,或者点击右侧应用步骤里的源,我们可以看到在公式栏里的query函数。

e54067477656bcce7a37f95c97085186.png

eb6d48cb0e0a26def2547d7324dd7cbe.png

在这里它使用的是Table.NestedJoin函数

https://docs.microsoft.com/zh-cn/powerquery-m/table-nestedjoin

在官方文档里的介绍如下

Table.NestedJoin(table1 as table,key1 as any,table2 as any,key2 as any,newColumnName as text, optionaljoinKind as nullable number, optionalkeyEqualityComparers as nullable list) as table

= Table.NestedJoin(BI, {"GID"}, ERP, {"GID"}, "ERP", JoinKind.RightOuter)

我们对比官方介绍和我们通过视窗操作自动生成的函数来了解这个函数。

table1 as table:选择表格1(也就是查询生成的结果表),我们选择的是BI

key1 as any : 选择任意格式的关键字段。我们选择的是BI表里的GID字段。它需要用列表形式展示。{"GID"},大括号就是query的列表

table2,key2同上

newColumnName as Text :设置文本格式的新列名。它会把关联生成的数据存储在这个列里。我们的例子中就是ERP列。5ecc14f2941ca36a9fee0047cad9e766.png

optional joinKind as nullable number :可选择的连接类型。连接的在上面的截图里我们介绍过了。这里我们在介绍下它的参数名称。在query函数列表里有下面这几个

  • JoinKind.FullOuter :全外连接
  • JoinKind.Inner : 内连接
  • JoinKind.LeftAnti : 左反
  • JoinKind.LeftOuter :左外连接
  • JoinKind.RightAnti :右反
  • JoinKind.RightOuter :右外连接
在上面的案例中,我们选择的是RightOuter。以后我们仔细介绍query的M函数,之前的多篇文章我们也有所涉及。在数据量相对不大的时候(大概300万内吧看电脑性能),M函数真的很好用。比如上的Table函数,还有List函数、Text函数等,数据清洗利器!上周给一研究院的老同学用query计算了三组实验数据。每组50组个数,要先计算3组数据的笛卡尔积,然后再分别根据公式计算值。50*50*50笛卡尔积后的数据是12万行。 query 分分钟就完成了这组计算。而且后期数据如果发生变化,只需要修改源数据,然后点击刷新就立马生成最新结果。

pandas两表核对

66e6496a89b28a1687e23e9b20901ff6.png

上面说完了query的模式,下面我们聊聊python的数据分析库pandas。query好用是好用,但遇到千万级别的数据量就会慢到怀疑人生,它会多次加载,计算性能也会很慢。这时就得用python这种编程数据处理工具了。 Python、pandas安装关于python的安装、环境设置,大家可以百度即可。python免费,可以官网直接下载就行。现在流行使用的python版本是3.7.https://www.python.org/downloads/ 这是下载网址https://www.python.org/ftp/python/3.7.8/python-3.7.8-amd64.exe我使用的是3.7.8版本

8de92d0275f782a787a0839fe1f8ea4f.png

安装完成之后在cmd命令窗口里输入python --version查看python版本

56c518546fb34f4c5e00e2ca0f163ba7.png

或者直接输入python,启用python

49ee30561d789b54b5cbc128eb39e7e1.png

有兴趣的朋友也可以自行百度安装下Ipython、Jupyter NoteBook。尤其是Jupyter Notebook是非常好用的python工具。Ipython和Jupyter Notebook都可以带有代码自动补充功能。但原生python并没有。启用Ipython

fe81c69093346aa7eb7ea025ca497cce.png

启用Jupyter Notebook

167fa733de8f81c030effae5746c4b93.png

Jupyter Notebook会在浏览器上打开,并在浏览器上使用。如下图我们生成2行5列的符合正态分布(均值为0,方差为1)的随机数。

e492387c55a0663e195b0faa5ad29e80.png

pandas、numpy等库安装的话,可以从cmd窗口输入pip install pandas( 我的已经安装完毕 )numpy的话就是pip install numpy其他库的话就是pip install 库名称。其他关于pip的安装、更新操作大家可自行百度。

619f49fa3995bd929942e94571c56e5d.png

pandas文件读取https://pandas.pydata.org/pandas-docs/stable/user_guide/index.html这是pandas的官方文档。因为在python版1.0里使用的是从sql导出的csv或者Excel格式文件加载到pandas里,然后进行的数据核对,所以我们首先来说下如何读取csv、Excel格式文件。pandas文档左侧是目录,第一个主题便是IO工具,即输入输出工具。

2679d1e07bb90abb20b092a836ab3940.png

比较主流文件类型基本都已经涵盖了。csv、json、html、excel、HDF5、stata、sas、spass、sql等等。读取文件的时候需要注意文件路径问题,路径中有中文字符的容易报错。我们先设置路径变量path path = r'C:\Users\Administrator\Desktop\test\BI.csv'用r的原因是路径中存在反斜杠\然后我们就可以调用pandas的read_csv来读取csv文件了。df = pd.read_csv(path)

958271d28666c7996955ef8cf1fcc9e0.png

当然如果文件格式是excel的话path_excel = r'C:\Users\Administrator\Desktop\test\BI.xlsx'df_excel = pd.read_excel(path_excel)

d1606a596d96bba3b03c4f75c2addd43.png

%time是Jupyter Notebook里的魔法函数,可以显示代码执行时间。如上图所示,excel的读取时间花了8.73s我们多执行几次看看平均时间。7次执行的平均时间是7.21s。

a619676a1136a5218408518ae5fda713.png

我们再看看读取csv格式文件的速度,7次读取的平均时间是174ms

107bc7313011c5ba3e48d80a05038970.png

虽然csv文件在 同样数据情况下,csv文件大小为13.6MB,而excel为8MB。但是csv的读取时间却是excel的1/50左右。 pandas的Merge方法

读取完数据之后我们如何去进行比较呢?

我们先来看看读取完的数据是什么类型的.

通过.info()方法可以看到数据显示为DataFrame格式。其实这正是我们用pandas的read方法读取数据的原因,它读取完就是DataFrame格式,而无需另行转换。

1fd29e68cd607634faa19bb3a9fa7247.png

DataFrame可以简单理解为一个二维表,有行有列。

然后我们看看pandas文档对于merge方法的介绍,在第4章节里介绍的就是merge,join和concatenate。

5dad22e9c66ae55760b2309f2ed4f7f8.png

concatenate可横向连接,也可纵向连接。功能强大,使用百变

merge是数据库风格的连接,也就是我们在query中介绍的合并查询的那几种。被介绍为类似数据库sql连接类型的功能强大、高性能的内存连接操作。

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=('_x', '_y'), copy=True, indicator=False,validate=None)

上面这是merge方法的参数

left为左侧表,right为右侧表(其实也可以是series,DataFrame类型的单维表,可以简单理解为一行或者一列)

how:是两边的连接方式。 'left''right''outer''inner'。它这里有四种选项。

on:连接的列或者索引级别名称,是必须同时存在于两个表里的。如果没有找到连接的名称,那么左右两表的交集将被当做连接字段。

(DataFrame结构有索引和列的概念,索引可以为多层,可以简单理解为excel透视表的行分组。)

left_on和right_on:如果on参数不设置或者没有同名的存在。那么可以分别在这俩参数里指定左右两表的连接字段名称。

left_index和right_index:如果为TRUE,那么基于两表的索引建立连接

suffixes:用于设置两表重叠字段的名称的。默认是('_x','_y'),分别给左表重叠字段名称添加后缀_x,给右表添加_y

indicator:如果为True,则产生一列名为"_merge"的列,它的值为left_only(左表独有),right_only(右表独有),both(两表都有)。这3个值的出现是根据how的值来定的。

了解了merge的用法,我们就可以用它来查找左表、右表独有的内容了。

merge_df = pd.merge(left=left_df,right=right_df,how = 'outer',on = ['GID'],left_index=False,

                    right_index=False,sort=False,indicator=True)

这里我们只需要一行代码就完成了两表的比对。下图可见我们比对后生成的数据。PID这个重复的列名各自加了后缀。其他列名因为大小写不同而不认为相同。在最后有一个_merge列

fd3118e6f4f5fbc0588a879b2585ddf9.png

_merge列的值只有3个。(unique()方法可查看列的非重复值,merge_df['_merge'].unique(),这样写也可以)

b28699c26ae2bab116f8e8c27d6d0e20.png

可通过merge_df[merge_df['_merge'] == 'right_only']来筛选right_only的列

28330dcf285d0777619f319f103554d4.png

merge_df[merge_df['_merge'] == 'right_only'].to_excel('right_only.xlsx')

这行代码可以将过滤结果输出为excel文件。

5602fe15f555ba1e398a44089cdf769e.png

虽然啰啰嗦嗦3千多字,但实际操作却只是几行代码的事。这样我们就可以通过几行代码完成整个表数据的核对。我的数据样本是10万行。即使是几百万、几千万行(只要内存够),Python pandas都可以迅速完成你的命令!

相关文章:

  • C语言使用递归法计算n的阶乘
  • python解释器与编译环境_python入门之解释器环境安装
  • HDU 1299 基础数论 分解
  • simpledateformat格式_2020 年,你还在使用 Java 中的 SimpleDateFormat 吗?
  • 人生苦短我学python谁说的_人生苦短,我学python
  • [PY3]——logging
  • python笔记视频_python视频笔记之三(循环和函数)
  • 洛谷P3003 [USACO10DEC]苹果交货Apple Delivery
  • linux添加ip白名单_为什么IP代理需要授权?
  • 事件对象练习
  • yii beforeaction 如何赋值全局变量_讲讲 js 的内存泄漏、如何监控和分析
  • Java基础总结--变量、运算符总结
  • boolean mybatis_mybatis的环境搭建以及问题
  • 软件工程实践2017第二次作业
  • python django步骤_python - django (创建到运行流程)
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • download使用浅析
  • HTTP--网络协议分层,http历史(二)
  • Invalidate和postInvalidate的区别
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Java小白进阶笔记(3)-初级面向对象
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • jQuery(一)
  • Making An Indicator With Pure CSS
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • XML已死 ?
  • 多线程 start 和 run 方法到底有什么区别?
  • 如何合理的规划jvm性能调优
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 中文输入法与React文本输入框的问题与解决方案
  • postgresql行列转换函数
  • #define 用法
  • #ifdef 的技巧用法
  • $.ajax()方法详解
  • (003)SlickEdit Unity的补全
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (LeetCode C++)盛最多水的容器
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (六)vue-router+UI组件库
  • (四)图像的%2线性拉伸
  • (一)认识微服务
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .Net FrameWork总结
  • .NET开源项目介绍及资源推荐:数据持久层
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [Android]一个简单使用Handler做Timer的例子
  • [BUAA软工]第一次博客作业---阅读《构建之法》
  • [C++提高编程](三):STL初识
  • [FC][常见Mapper IRQ研究]
  • [Geek Challenge 2023] web题解
  • [iOS]中字体样式设置 API
  • [linux] C语言Linux系统编程进程基本概念