Pandas高级教程之:Dataframe的合并
文章目录
- 简介
- 使用concat
- 使用append
- 使用merge
- 使用join
- 覆盖数据
简介
Pandas提供了很多合并Series和Dataframe的强大的功能,通过这些功能可以方便的进行数据分析。本文将会详细讲解如何使用Pandas来合并Series和Dataframe。
使用concat
concat是最常用的合并DF的方法,先看下concat的定义:
pd.concat(objs, axis=0, join='outer', ignore_index=False, keys=None,levels=None, names=None, verify_integrity=False, copy=True)
看一下我们经常会用到的几个参数:
objs是Series或者Series的序列或者映射。
axis指定连接的轴。
join
: {‘inner’, ‘outer’}, 连接方式,怎么处理其他轴的index,outer表示合并,inner表示交集。
ignore_index: 忽略原本的index值,使用0,1,… n-1来代替。
copy:是否进行拷贝。
keys:指定最外层的多层次结构的index。
我们先定义几个DF,然后看一下怎么使用concat把这几个DF连接起来:
In [1]: df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],...: 'B': ['B0', 'B1', 'B2', 'B3'],...: 'C': ['C0', 'C1', 'C2', 'C3'],...: 'D': ['D0', 'D1', 'D2', 'D3']},...: index=[0, 1, 2, 3])...: In [2]: df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],...: 'B': ['B4', 'B5', 'B6', 'B7'],...: 'C': ['C4', 'C5', 'C6', 'C7'],...: 'D': ['D4', 'D5', 'D6', 'D7']},...: index=[4, 5, 6, 7])...: In [3]: df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],...: 'B': ['B8', 'B9', 'B10', 'B11'],...: 'C': ['C8', 'C9', 'C10', 'C11'],...: 'D': ['D8', 'D9', 'D10', 'D11']},...: index=[8, 9, 10, 11])...: In [4]: frames = [df1, df2, df3]In [5]: result = pd.concat(frames)
df1,df2,df3定义了同样的列名和不同的index,然后将他们放在frames中构成了一个DF的list,将其作为参数传入concat就可以进行DF的合并。
举个多层级的例子:
In [6]: result = pd.concat(frames, keys=['x', 'y', 'z'])
使用keys可以指定frames中不同frames的key。
使用的时候,我们可以通过选择外部的key来返回特定的frame:
In [7]: result.loc['y']
Out[7]: A B C D
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
上面的例子连接的轴默认是0,也就是按行来进行连接,下面我们来看一个例子按列来进行连接,如果要按列来连接,可以指定axis=1:
In [8]: df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],...: 'D': ['D2', 'D3', 'D6', 'D7'],...: 'F': ['F2', 'F3', 'F6', 'F7']},...: index=[2, 3, 6, 7])...: In [9]: result = pd.concat([df1, df4], axis=1, sort=False)
默认的 join='outer'
,合并之后index不存在的地方会补全为NaN。
下面看一个join='inner’的情况:
In [10]: result = pd.concat([df1, df4], axis=1, join='inner')
join=‘inner’ 只会选择index相同的进行展示。
如果合并之后,我们只想保存原来frame的index相关的数据,那么可以使用reindex:
In [11]: result = pd.concat([df1, df4], axis=1).reindex(df1.index)
或者这样:
In [12]: pd.concat([df1, df4.reindex(df1.index)], axis=1)
Out[12]: A B C D B D F
0 A0 B0 C0 D0 NaN NaN NaN
1 A1 B1 C1 D1 NaN NaN NaN
2 A2 B2 C2 D2 B2 D2 F2
3 A3 B3 C3 D3 B3 D3 F3
看下结果:
可以合并DF和Series:
In [18]: s1 = pd.Series(['X0', 'X1', 'X2', 'X3'], name='X')In [19]: result = pd.concat([df1, s1], axis=1)
如果是多个Series,使用concat可以指定列名:
In [23]: s3 = pd.Series([0, 1, 2, 3], name='foo')In [24]: s4 = pd.Series([0, 1, 2, 3])In [25]: s5 = pd.Series([0, 1, 4, 5])
In [27]: pd.concat([s3, s4, s5], axis=1, keys=['red', 'blue', 'yellow'])
Out[27]: red blue yellow
0 0 0 0
1 1 1 1
2 2 2 4
3 3 3 5
使用append
append可以看做是concat的简化版本,它沿着axis=0
进行concat:
In [13]: result = df1.append(df2)
如果append的两个 DF的列是不一样的会自动补全NaN:
In [14]: result = df1.append(df4, sort=False)
如果设置ignore_index=True,可以忽略原来的index,并重写分配index:
In [17]: result = df1.append(df4, ignore_index=True, sort=False)
向DF append一个Series:
In [35]: s2 = pd.Series(['X0', 'X1', 'X2', 'X3'], index=['A', 'B', 'C', 'D'])In [36]: result = df1.append(s2, ignore_index=True)
使用merge
和DF最类似的就是数据库的表格,可以使用merge来进行类似数据库操作的DF合并操作。
先看下merge的定义:
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)
Left, right是要合并的两个DF 或者 Series。
on代表的是join的列或者index名。
left_on:左连接
right_on
:右连接
left_index
: 连接之后,选择使用左边的index或者column。
right_index
:连接之后,选择使用右边的index或者column。
how:连接的方式,'left'
, 'right'
, 'outer'
, 'inner'
. 默认 inner
.
sort
: 是否排序。
suffixes
: 处理重复的列。
copy
: 是否拷贝数据
先看一个简单merge的例子:
In [39]: left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],....: 'A': ['A0', 'A1', 'A2', 'A3'],....: 'B': ['B0', 'B1', 'B2', 'B3']})....: In [40]: right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],....: 'C': ['C0', 'C1', 'C2', 'C3'],....: 'D': ['D0', 'D1', 'D2', 'D3']})....: In [41]: result = pd.merge(left, right, on='key')
上面两个DF通过key来进行连接。
再看一个多个key连接的例子:
In [42]: left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],....: 'key2': ['K0', 'K1', 'K0', 'K1'],....: 'A': ['A0', 'A1', 'A2', 'A3'],....: 'B': ['B0', 'B1', 'B2', 'B3']})....: In [43]: right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],....: 'key2': ['K0', 'K0', 'K0', 'K0'],....: 'C': ['C0', 'C1', 'C2', 'C3'],....: 'D': ['D0', 'D1', 'D2', 'D3']})....: In [44]: result = pd.merge(left, right, on=['key1', 'key2'])
How 可以指定merge方式,和数据库一样,可以指定是内连接,外连接等:
合并方法 | SQL 方法 |
---|---|
left
|
LEFT OUTER JOIN
|
right
|
RIGHT OUTER JOIN
|
outer
|
FULL OUTER JOIN
|
inner
|
INNER JOIN
|
In [45]: result = pd.merge(left, right, how='left', on=['key1', 'key2'])
指定indicator=True ,可以表示具体行的连接方式:
In [60]: df1 = pd.DataFrame({'col1': [0, 1], 'col_left': ['a', 'b']})In [61]: df2 = pd.DataFrame({'col1': [1, 2, 2], 'col_right': [2, 2, 2]})In [62]: pd.merge(df1, df2, on='col1', how='outer', indicator=True)
Out[62]: col1 col_left col_right _merge
0 0 a NaN left_only
1 1 b 2.0 both
2 2 NaN 2.0 right_only
3 2 NaN 2.0 right_only
如果传入字符串给indicator,会重命名indicator这一列的名字:
In [63]: pd.merge(df1, df2, on='col1', how='outer', indicator='indicator_column')
Out[63]: col1 col_left col_right indicator_column
0 0 a NaN left_only
1 1 b 2.0 both
2 2 NaN 2.0 right_only
3 2 NaN 2.0 right_only
多个index进行合并:
In [112]: leftindex = pd.MultiIndex.from_tuples([('K0', 'X0'), ('K0', 'X1'),.....: ('K1', 'X2')],.....: names=['key', 'X']).....: In [113]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],.....: 'B': ['B0', 'B1', 'B2']},.....: index=leftindex).....: In [114]: rightindex = pd.MultiIndex.from_tuples([('K0', 'Y0'), ('K1', 'Y1'),.....: ('K2', 'Y2'), ('K2', 'Y3')],.....: names=['key', 'Y']).....: In [115]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],.....: 'D': ['D0', 'D1', 'D2', 'D3']},.....: index=rightindex).....: In [116]: result = pd.merge(left.reset_index(), right.reset_index(),.....: on=['key'], how='inner').set_index(['key', 'X', 'Y'])
支持多个列的合并:
In [117]: left_index = pd.Index(['K0', 'K0', 'K1', 'K2'], name='key1')In [118]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],.....: 'B': ['B0', 'B1', 'B2', 'B3'],.....: 'key2': ['K0', 'K1', 'K0', 'K1']},.....: index=left_index).....: In [119]: right_index = pd.Index(['K0', 'K1', 'K2', 'K2'], name='key1')In [120]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],.....: 'D': ['D0', 'D1', 'D2', 'D3'],.....: 'key2': ['K0', 'K0', 'K0', 'K1']},.....: index=right_index).....: In [121]: result = left.merge(right, on=['key1', 'key2'])
使用join
join将两个不同index的DF合并成一个。可以看做是merge的简写。
In [84]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],....: 'B': ['B0', 'B1', 'B2']},....: index=['K0', 'K1', 'K2'])....: In [85]: right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],....: 'D': ['D0', 'D2', 'D3']},....: index=['K0', 'K2', 'K3'])....: In [86]: result = left.join(right)
可以指定how来指定连接方式:
In [87]: result = left.join(right, how='outer')
默认join是按index来进行连接。
还可以按照列来进行连接:
In [91]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],....: 'B': ['B0', 'B1', 'B2', 'B3'],....: 'key': ['K0', 'K1', 'K0', 'K1']})....: In [92]: right = pd.DataFrame({'C': ['C0', 'C1'],....: 'D': ['D0', 'D1']},....: index=['K0', 'K1'])....: In [93]: result = left.join(right, on='key')
单个index和多个index进行join:
In [100]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],.....: 'B': ['B0', 'B1', 'B2']},.....: index=pd.Index(['K0', 'K1', 'K2'], name='key')).....: In [101]: index = pd.MultiIndex.from_tuples([('K0', 'Y0'), ('K1', 'Y1'),.....: ('K2', 'Y2'), ('K2', 'Y3')],.....: names=['key', 'Y']).....: In [102]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],.....: 'D': ['D0', 'D1', 'D2', 'D3']},.....: index=index).....: In [103]: result = left.join(right, how='inner')
列名重复的情况:
In [122]: left = pd.DataFrame({'k': ['K0', 'K1', 'K2'], 'v': [1, 2, 3]})In [123]: right = pd.DataFrame({'k': ['K0', 'K0', 'K3'], 'v': [4, 5, 6]})In [124]: result = pd.merge(left, right, on='k')
可以自定义重复列名的命名规则:
In [125]: result = pd.merge(left, right, on='k', suffixes=('_l', '_r'))
覆盖数据
有时候我们需要使用DF2的数据来填充DF1的数据,这时候可以使用combine_first:
In [131]: df1 = pd.DataFrame([[np.nan, 3., 5.], [-4.6, np.nan, np.nan],.....: [np.nan, 7., np.nan]]).....: In [132]: df2 = pd.DataFrame([[-42.6, np.nan, -8.2], [-5., 1.6, 4]],.....: index=[1, 2]).....:
In [133]: result = df1.combine_first(df2)
或者使用update:
In [134]: df1.update(df2)
本文已收录于 http://www.flydean.com/04-python-pandas-merge/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
Pandas高级教程之:Dataframe的合并相关推荐
- Pandas高级教程之:GroupBy用法
文章目录 简介 分割数据 多index get_group dropna groups属性 index的层级 group的遍历 聚合操作 通用聚合方法 同时使用多个聚合方法 NamedAgg 不同的列 ...
- Pandas高级教程之:统计方法
文章目录 简介 变动百分百 Covariance协方差 Correlation相关系数 rank等级 简介 数据分析中经常会用到很多统计类的方法,本文将会介绍Pandas中使用到的统计方法. 变动百分 ...
- Pandas高级教程之:plot画图详解
文章目录 简介 基础画图 其他图像 bar stacked bar barh Histograms box Area Scatter Hexagonal bin Pie 在画图中处理NaN数据 其他作 ...
- Pandas高级教程之:category数据类型
文章目录 简介 创建category 使用Series创建 使用DF创建 创建控制 转换为原始类型 categories的操作 获取category的属性 重命名categories 使用**add_ ...
- Pandas高级教程之:处理缺失数据
文章目录 简介 NaN的例子 整数类型的缺失值 Datetimes 类型的缺失值 None 和 np.nan 的转换 缺失值的计算 使用fillna填充NaN数据 使用dropna删除包含NA的数据 ...
- Pandas高级教程之:处理text数据
文章目录 简介 创建text的DF String 的方法 columns的String操作 分割和替换String String的连接 使用 .str来index extract extractall ...
- Pandas高级教程之:自定义选项
文章目录 简介 常用选项 get/set 选项 经常使用的选项 最大展示行数 超出数据展示 最大列的宽度 显示精度 零转换的门槛 列头的对齐方向 简介 pandas有一个option系统可以控制pan ...
- iText7高级教程之html2pdf——7.关于pdfHTML经常问的问题
本章是一些问题的总结,iText官网罗列了常见的一些问题,让我们能更加了解pdfTML.一下是原文和链接,在这会一一翻译: Over the years, we've received many ...
- iText7高级教程之html2pdf——6.在pdfHTML中使用字体
作者:CuteXiaoKe 微信公众号:CuteXiaoKe 到目前为止,我们还没有花太多的精力来研究将HTML转换为PDF时使用的字体.我们知道Helvetica是iText在没有指定字体时使用 ...
- iText7高级教程之html2pdf——1.从Hello HTML开始
作者:CuteXiaoKe 微信公众号:CuteXiaoKe 在本章,我们通过不同的方法把一个简单的HTML文件转换为PDF文件.HTML文件的内容包含一个"TEST"标题,一 ...
最新文章
- Go的变量到底在堆还是栈中分配
- 《图像处理实例》之 曲线之间距离求解
- PHP面向对象2之变量、方法
- windwos cakephp mysql apache_配置Apache2.2+PHP5+CakePHP1.2+MySQL5运行环境
- sql单表简单的分页脚本
- (2)Spring框架----IOC基础快速入门
- 计算机游戏 ppt背景图片,课件背景图片大全
- gtk下的messagebox
- 【Android Test】糟心的“Empty test suite ”异常
- Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之部署到Linux
- 如何随意复制网页上的文字
- SDN之旅—mininet(在Windows系统上)安装
- 操作系统|时间片轮转调度算法(RR)
- PMP考试常见图表讲解:迭代燃尽图、S曲线图……
- nova launcher_如何安装Nova Launcher以获得更强大,可自定义的Android主屏幕
- 腾讯云服务器文件解压,使用腾讯云函数SCF快速解压对象存储COS中的ZIP文件
- 对Riak Core的探索 (1) Hello
- 华硕路由器虚拟服务器,路由器也能作虚拟主机?
- 计算机网络论文2020年8000字,2020年计算机网络技术论文范文.docx
- java 摄像头 win7_JAVA摄像头调用方法_实例源码介绍—Win7