【数据处理包Pandas】DataFrame对象的合并

目录

    • 前言
    • 一、回顾Numpy数组的合并
    • 二、concat方法合并DataFrame对象
    • 三、append方法的使用
    • 四、merge方法合并DataFrame对象
      • (一)比较merge与concat
      • (二)参数on、left_on和right_on的用法
      • (三)合并时四种不同的连接规则
      • (四)left_index与right_index参数的用法
    • 五、join方法的使用
    • 六、小结


前言

合并是指把两个甚至多个 DataFrame 对象连接起来,与合并相关的方法有四个:concatappendmergejoin

它们的主要区别:

  • concat支持多个 DataFrame 对象的水平和垂直排放,即可以列合并也可以行合并;但与merge不同,它的合并不基于列值匹配。
  • append只能行合并,与concat做行合并相比,形式更为简化。
  • merge的合并是列合并,合并时会基于列值匹配,类似于 SQL 语言的多表连接查询;merge只能对两个 DataFrame 对象同时合并。
  • join也是列合并,但它的合并不是基于列值匹配而是基于行索引/列索引的匹配,特定情况下与concat做列合并的效果相当。
import pandas as pd
import numpy as np

一、回顾Numpy数组的合并

Numpy 数组的合并使用np.concatenate()方法。

1、多个一维列表合并的情形

x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
np.concatenate([x, y, z])   # 因为x、y和z都是一维的,所以合并以后也是一维的
array([1, 2, 3, 4, 5, 6, 7, 8, 9])

2、二维Numpy数组合并的情形

m = np.array([[1,2],[3,4]])
n = np.array([[5,6],[7,8]])
p = np.array([[9,10],[11,12]])
# 默认是按行方向合并,相当于axis=0
np.concatenate([m,n,p]) 
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10],
       [11, 12]])
np.vstack((m,n,p))   # 等价于np.concatenate([m,n,p],axis=0)
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10],
       [11, 12]])

如果按列合并,必须使用axis=1参数。

np.concatenate([m,n,p],axis=1) 
array([[ 1,  2,  5,  6,  9, 10],
       [ 3,  4,  7,  8, 11, 12]])
np.hstack((m,n,p))   # 等价于np.concatenate([m,n,p],axis=1) 
array([[ 1,  2,  5,  6,  9, 10],
       [ 3,  4,  7,  8, 11, 12]])

二、concat方法合并DataFrame对象

np.concatenatepd.concat最主要的差异就是 Pandas 合并时会保留索引,并且允许索引是重复的。

pd.concat既可以行合并,也可以列合并;并且沿着哪个轴合并,合并对象上该轴的索引将全部保留;例如按行合并(对应于axis=0),此时参与合并的所有 DataFrame 对象的行索引则全部保留,并且由上到下按序排列。

而另一轴的索引取决于join参数是'outer'还是'inner',前者做并集后者做交集;例如当按行合并(对应于axis=0)时,另一轴的索引是指列索引,结果的列索引将由参与合并的所有 DataFrame 对象的列索引做并集(对应于join='outer')或做交集(对应于join='outer')而得到

pd.concat()方法原型:
pd.concat(objs, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=False, copy=True)

  • objs:要连接的 pandas 对象列表或字典。
  • axis:指定连接的轴,0 表示按行连接,1 表示按列连接。
  • join:指定连接方式,‘inner’ 表示取交集,‘outer’ 表示取并集。
  • ignore_index:如果为 True,则忽略原始索引,生成新的连续索引。
  • keys:使用层次化索引进行连接。
  • levels:如果 keys 参数被指定,则 levels 参数表示索引层级。
  • names:如果 keys 参数被指定,则 names 参数表示索引名称。
  • verify_integrity:如果为 True,则检查结果对象是否包含重复索引。
  • sort:如果为 True,则按索引进行排序。
  • copy:如果为 False,则不复制数据。
df1 = pd.DataFrame({'A':['A1','A2'],'B':['B1','B2'],'C':['C1','C2']},index=[1,2])
df1

在这里插入图片描述

df2 = pd.DataFrame({'A':['A3','A4'],'B':['B3','B4'],'D':['D3','D4']},index=[1,3])
df2

在这里插入图片描述

没有axis=0或者明确给出axis=0,都是按行合并,此时列索引取并集。

pd.concat([df1,df2])

在这里插入图片描述

明确给出axis=0,则是按列合并,此时行索引取并集。

pd.concat([df1,df2],axis=1)

在这里插入图片描述

之所以上面两个例子都是并集,原因在于concatjoin参数默认值是'outer',表示取并集(类似于SQL的外连接);而当明确指明join='inner'时,将取交集计算结果(类似于SQL的内连接)。

join='inner'时,按行合并,则列索引取交集。

pd.concat([df1,df2],join='inner')

在这里插入图片描述

补充:ignore_index参数的使用:

ignore_index=True会忽略原来的行索引,使用新的位置索引。

pd.concat([df1,df2],join='inner',ignore_index=True)

在这里插入图片描述

join='inner'时,按列合并,则行索引取交集。

pd.concat([df1,df2],axis=1,join='inner')

在这里插入图片描述

三、append方法的使用

append可以把两个 DataFrame 对象按行合并,其功能等价于上面讲的pd.concat([df1,df2])

df.append()方法原型:
DataFrame.append(other, ignore_index=False, verify_integrity=False, sort=None)

  • other:可以是 DataFrame、Series 或者包含 DataFrame 或 Series 的列表,表示要附加到原始 DataFrame 的数据。
  • ignore_index:如果为 True,则忽略附加的数据的索引,并为结果 DataFrame 分配一个新的整数索引。默认为 False。
  • verify_integrity:如果为 True,则在附加操作之前检查结果 DataFrame 中的新索引是否唯一。如果新索引不唯一,则会引发 ValueError。默认为 False。
  • sort:如果为 True,则对结果 DataFrame 进行排序。默认为 None,表示不进行排序。
df1.append(df2)  

在这里插入图片描述

如果要使用append方法为df1对象增加记录行,需要把要增加的记录行构成df2,并且写成如下形式:df1=df1.append(df2)。上面语句之所以要赋值,是因为 Pandas 中的append不会直接修改原始的df1对象。

四、merge方法合并DataFrame对象

(一)比较merge与concat

df3 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],
                    'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})
df3

在这里插入图片描述

df4 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],
                    'hire_date': [2004, 2008, 2012, 2014]})
df4

在这里插入图片描述

下面的示例比较mergeconcat,可以看出:

(1)merge主要基于列值匹配而进行列合并,类似于SQL中的连接操作,而concat并没有基于列值匹配进行合并。

(2)merge中的两个合并对象只用逗号分隔,而concat中的两个合并对象要构成列表。

一对一连接:在起连接作用的关键列(employee)上,通过列值匹配进行合并。

pd.merge(df3, df4)

在这里插入图片描述

concat并没有基于两个employee列的相同值匹配进行合并。

pd.concat([df3,df4],axis=1)

在这里插入图片描述

df5 = pd.DataFrame({'group': ['Accounting', 'Accounting',
                              'Engineering', 'Engineering', 'HR', 'HR'],
                    'skills': ['math', 'spreadsheets', 'coding', 'linux',
                               'spreadsheets', 'organization']})
df5

在这里插入图片描述

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

  • left:要合并的左侧 DataFrame。
  • right:要合并的右侧 DataFrame。
  • how:指定要使用的合并方法。可选值包括:
    ‘left’:保留左侧 DataFrame 中的所有行,并将右侧 DataFrame 中与左侧匹配的行合并到结果中。如果右侧 DataFrame 中没有匹配的行,则将 NaN 填充到结果中的相应位置。
    ‘right’:保留右侧 DataFrame 中的所有行,并将左侧 DataFrame 中与右侧匹配的行合并到结果中。如果左侧 DataFrame 中没有匹配的行,则将 NaN 填充到结果中的相应位置。
    ‘inner’:保留左右两侧 DataFrame 中都存在的行,并将它们合并到结果中。
    ‘outer’:保留左右两侧 DataFrame 中的所有行,并将它们合并到结果中。如果某一侧 DataFrame 中没有匹配的行,则将 NaN 填充到结果中的相应位置。
  • on:指定要合并的列(或列的名称)。如果两个 DataFrame 中的列名相同,并且没有指定该参数,则将这些列作为合并的键。如果要合并的列名不同,可以分别使用left_onright_on参数指定左右两侧的列名。
  • left_on:指定左侧 DataFrame 中用作合并键的列。
  • right_on:指定右侧 DataFrame 中用作合并键的列。
  • left_index:如果为 True,则使用左侧 DataFrame 的索引作为合并键。
  • right_index:如果为 True,则使用右侧 DataFrame 的索引作为合并键。
  • sort:如果为 True,则对合并后的结果进行排序。
  • suffixes:如果在合并过程中遇到了重叠的列名,则添加到重叠列名的后缀。
  • copy:如果为 False,则不复制数据。默认为 True。
  • indicator:如果为 True,则在结果中添加一个名为 “_merge” 的列,指示每行的合并方式(如 “left_only”、“right_only”、“both”)。
  • validate:验证合并操作的类型。可选值包括:“one_to_one”、“one_to_many”、“many_to_one”、“many_to_many”。

(二)参数on、left_on和right_on的用法

使用on参数显式设置起连接作用的关键列是两个 DataFrame 对象的group列。

pd.merge(df3, df5,on='group') 

在这里插入图片描述

当两个 DataFrame 的关键列的列名不同时,需要使用left_onright_on参数实现列值匹配。

df6 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],
                    'salary': [70000, 80000, 120000, 90000]})
pd.merge(df3, df6, left_on="employee", right_on="name")  

在这里插入图片描述

上面合并后employee列和name列是重复的,可以使用drop方法删除多余的name列。

pd.merge(df3, df6, left_on="employee", right_on="name") .drop('name',axis=1)  

在这里插入图片描述

(三)合并时四种不同的连接规则

重新设置df3包含空数据(NaN)。

df3 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue','Tom'],
                    'group': ['Accounting', 'Engineering', 'Engineering', 'HR',np.NaN]})
df3   # 注意Tom目前没有所属部门

在这里插入图片描述

df7 = pd.DataFrame({'group': ['Accounting', 'Engineering', 'HR','Sale'],
                    'supervisor': ['Carly', 'Guido', 'Steve','Jack']})
df7

在这里插入图片描述

merge默认的连接方式是'inner'(即内连接),基于列值匹配时取交集,或者明确指明连接方式为how='inner',两个数据集能匹配上的记录才会出现在结果中。

pd.merge(df3,df7,how='inner')   # 等价于pd.merge(df3,df7)

在这里插入图片描述

how='outer'指明连接方式是外连接,此时基于列值匹配时取并集。两个数据集中不匹配的记录也都会出现在结果中(例如下面最后两条记录)。

pd.merge(df3,df7,how='outer')  

在这里插入图片描述

how='left'指明连接方式是左连接,此时基于列值匹配时会全部保留左边数据集的记录。而右边数据集中不匹配的记录则不会被合并到结果中。

注意Sale部门因为没有职员与之匹配,所以Sale部门没有出现在结果中。

pd.merge(df3,df7,how='left')

在这里插入图片描述

how='right'指明连接方式是右连接,此时基于列值匹配时会全部保留右边数据集的记录。而左边数据集中不匹配的记录则不会被合并到结果中。

注意:职员Tom因为没有部门与之匹配,所以Tom没有出现在结果中。

pd.merge(df3,df7,how='right')

在这里插入图片描述

(四)left_index与right_index参数的用法

merge既可以合并列,也可以合并索引,下面先设置employee为两个数据集df3df4的索引,然后基于该索引进行合并。

df3 = df3.set_index('employee')
df3

在这里插入图片描述

df4 = df4.set_index('employee')
df4

在这里插入图片描述

基于索引合并就需要使用left_indexright_index参数。

注意:基于索引合并只取交集,而不能指定join参数。

# pd.merge(df3,df4)   # 不使用left_index与right_index参数会出错
pd.merge(df3,df4,left_index=True,right_index=True)

在这里插入图片描述

五、join方法的使用

df1

在这里插入图片描述

df2

在这里插入图片描述

df.join()方法原型:
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)

  • other:要连接的另一个 DataFrame 或 Series 对象。
  • on:指定连接的列名或索引级别。如果为 None,则默认使用索引进行连接。
  • how:指定连接方式,默认为左连接(‘left’),可选值包括 ‘left’, ‘right’, ‘outer’, ‘inner’。
  • lsuffix:左侧 DataFrame 列名后缀,用于解决重叠的情况。
  • rsuffix:右侧 DataFrame 列名后缀,用于解决重叠的情况。
  • sort:如果为 True,则根据连接键对结果进行排序。

join方法就是基于索引进行的列合并,如果两个数据集有重复的列名,需指定lsuffixrsuffix参数。
join方法默认是左连接(how='left'),只保留左边的全部记录,对列除了加后缀不做处理,直接水平方向合并在一起。

df1.join(df2,lsuffix='_l', rsuffix='_r')

在这里插入图片描述

当连接方式how='outer'时,等价于axis=1时的concat合并。

df1.join(df2,lsuffix='_l', rsuffix='_r',how='outer')

在这里插入图片描述

pd.concat([df1,df2],axis=1)  # 与上面等价

在这里插入图片描述

六、小结

concat默认的合并方式是行拼接,取并集(axis=0,join='outer');

merge默认的合并方式是基于列值进行列拼接,取交集(how='inner');

join默认的合并方式是基于行索引进行列合并,并且默认为左连接。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c# wpf template ItemsPanel 简单试验

1.概要 2.代码 <Window x:Class"WpfApp2.Window9"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/…

软件测试(Junit5 单元测试框架)(五)

1. Junit单元测试框架 Junit 是 Java 的一个单元测试框架, 使用Selenium写自动化测试用例, 使用Junit 管理写好的测试用例. 2. 注解&#xff1a; Test 表示当前的这个方法是一个测试用例. 示例: 添加依赖 <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-…

[译] 教你如何用 Flutter 的 GestureDetector 构建自定义滑块

这个控件非常简单&#xff0c;我们接收完成的百分比值&#xff0c;以及正面和背面部分的颜色。主 Container 将背面颜色作为背景&#xff0c;我们将绘制正面部分去覆盖它。它的子节点是 Row&#xff0c;虽然它只包含一个子节点&#xff0c;但我保留了它&#xff0c;方便你添加另…

impala使用round函数保留小数失效

问题描述如标题所示 1.理论情况: round()函数,是用来做四舍五入的,比如:select round(2.126,2) 结果为:2.132.异常情况: 但是有时候会出现一些意料之外的情况,比如:select round(1/3,3) 结果为:0.33300000000000002正确的应该是:0.333截图效果示例如下: 3.解决办…

51之LCD1602与模块化编程

LCD1602&#xff0c;即我们开发板上附赠的那个液晶显示屏&#xff0c;我们通常可以使用这个液晶显示屏用来做调试工具&#xff0c;我们使用一下江科大提供的关于这个LCD1602的代码&#xff0c;用来为我们提供了类似C语言标准库里面的printf函数的用法&#xff0c;只是这个更加复…

非关系型数据库-----------探索 Redis高可用 、持久化、性能管理

目录 一、Redis 高可用 1.1什么是高可用 1.2Redis的高可用技术 二、 Redis 持久化 2.1持久化的功能 2.2Redis 提供两种方式进行持久化 三、Redis 持久化之----------RDB 3.1触发条件 3.1.1手动触发 3.1.2自动触发 3.1.3其他自动触发机制 3.2执行流程 3.3启动时加载…

AssetBundle在移动设备上丢失

1&#xff09;AssetBundle在移动设备上丢失 2&#xff09;Unity云渲染插件RenderStreaming&#xff0c;如何实现多用户分别有独立的操作 3&#xff09;如何在圆柱体类型的地图中编程玩家的输入 4&#xff09;Mixamo动画的根运动问题 这是第380篇UWA技术知识分享的推送&#xff…

如何处理ubuntu22.04LTS安装过程中出现“Daemons using outdated libraries”提示

Ubuntu 22.04 LTS 中使用命令行升级软件或安装任何新软件时&#xff0c;您可能收到“Daemons using outdated libraries”&#xff0c;“Which services should be restarted?”的提示&#xff0c;提示下面列出备选的重启服务&#xff0c;如下。 使用以下命令&#xff0c;能够…

盒子模型和伪元素

一.盒子模型的理解 我们平常在布局的时候,少不了盒子模型,今天讲解一下对盒子模型的理解。 理解:我们可以把盒子模型比作一个装着快递的包裹:里面的东西可以比作是内容,盒子里面的填充物可以比作是padding 外层的包装纸线条,可以比作是border&#xff0c;这个快递离另外个快递…

PS从入门到精通视频各类教程整理全集,包含素材、作业等(9)复发

PS从入门到精通视频各类教程整理全集&#xff0c;包含素材、作业等 最新PS以及插件合集&#xff0c;可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制&#xff0c;今天先分享到这里&#xff0c;后续持续更新 第一课 ——第三课素材文件 https://www.alipan.c…

20230405让WIN11暂停更新365天(暂停更新35天)

20230405让WIN11暂停更新365天&#xff08;暂停更新35天&#xff09; 2024/4/5 20:34 缘起&#xff0c;备用的笔记本电脑只要一开机&#xff0c;就会被比尔盖茨/微软提醒去更新/升级&#xff01; 不胜其烦&#xff01; 虽然可以在设置里设置暂停更新35天。但是也是不胜其扰&…

蓝桥杯杯赛之深度优先搜索优化《1.分成互质组》 《 2.小猫爬山》【dfs】【深度搜索剪枝优化】【搜索顺序】

文章目录 思想例题1. 分成互质组题目链接题目描述【解法一】【解法二】 2. 小猫爬山题目链接题目描述输入样例&#xff1a;输出样例&#xff1a;【思路】【WA代码】【AC代码】 思想 本质为两种搜索顺序&#xff1a; 枚举当前元素可以放入哪一组枚举每一组可以放入哪些元素 操…

解决windows下Qt Creator显示界面过大的问题

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 问题描述 解决方法 1、右击此电脑--->属性 2、点击高级系统设置--->点击环境变量 3、 找到系…

YOLOv3

YOLOv3 论文简介论文内容1. 采用darknet53FPN结构2. 边框预测保持与YOLOv2保持一致3. 沿用YOLOv2 kmeans生成先验anchors4.类别预测改为多分类格式 论文简介 论文&#xff1a;《YOLOv3: An Incremental Improvement》 作者&#xff1a;Joseph Redmon, Ali Farhadi 论文下载地址…

使用 Kafka 保证消息不丢失的策略及原理解析

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 一、引言 二. 持久化存储 2.1持久化存储原理&#xff1a; 2.2使用示例&#xff1a; …

7.java openCV4.x 入门-Mat之转换、重塑与计算

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

2024HW --->反序列化漏洞!

对于反序列化&#xff0c;这个漏洞也是常用的&#xff0c;不过涉及到的方面非常非常广&#xff0c;比其他漏洞也难很多 于是本篇文章就分成PHP和JAVA的反序列化来讲讲 1.反序列化 想要理解反序列化&#xff0c;首先就要理解序列化 序列化&#xff1a;把对象转换为字节序列的过…

Redis -- 缓存雪崩问题

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 可能原因 : 同一时间大量的key到期 ; 解决方案&#xff1a; 给不同的Key的TTL添加随机值 利用Redis集群提高服务的可用性 给缓存业务添加降…

【C++】哈希思想的应用(位图、布隆过滤器)及海量数据处理方法

文章目录 前言位图什么是位图简单实现一个自己的位图位图的应用场景 布隆过滤器位图的缺陷及布隆过滤器的提出布隆过滤器的概念简单实现一个自己的布隆过滤器布隆过滤器的优缺点布隆过滤器的应用场景 海量数据处理 前言 哈希思想的在实际中的应用除了哈希表这个数据结构之外还…

分享一个知识 -- bean的静态属性不会被封装返回

public class TeacherChartDataVo {private String name;// bateacherNameprivate List<Integer> data;private static String type "line";private static String stack "Total"; }比如&#xff1a;type 和stack 不会被返回。