pandas之DataFrame合并merge
一、merge
merge操作实现两个DataFrame之间的合并,类似于sql两个表之间的关联查询。merge的使用方法及参数解释如下:
pd.merge(left, right, on=None, how='inner', left_on=None, right_on=None, left_index=False, right_index=False,
sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
- left和right:第一个DataFrame和第二个DataFrame对象,merge只能实现两个DataFrame的合并,无法一次实现多个合并
- on:指定参考column,要求两个df必须至少有一个相同的column,默认为None以最多相同的column为参考
- how:合并的方式,默认为inner取参考column的交集,outer取并集保留所有行;outer、left、right中的缺失值都以NaN填充;left按照左边对象为参考进行合并即保留左边的所有行,right按照右边对象为参考进行合并即保留右边所有行,
- left_on=None和right_on=None:以上on是在两个df有相同的column的情况下使用,如果两个df没有相同的column,使用left_on和right_on分别指明左边和右边的参考column
- left_index和right_index:指定是否以索引为参考进行合并
- sort:合并结果是否按on指定的参考进行排序
- suffixed:合并后如果有重复column,分别加上什么后缀
下面对每个参数进行演示
on:指定参考column,如果不指定默认为None,以两者相同列的最多数为参考;index重新生成为从0开始的整数。
df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n',])
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H'],'key4':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,on='key1'))
print(pd.merge(df1,df2,on='key2'))
print(pd.merge(df1,df2,on=['key1','key2']))
print(pd.merge(df1,df2)) #可以看到不加on参数,系统自动以个数最多的相同column为参考
# key1 key2 key3
# k a e i
# l b f j
# m c g k
# n d h l
# key1 key2 key4
# p a e i
# q B f j
# u c g K
# v d H L
# key1 key2_x key3 key2_y key4
# 0 a e i e i
# 1 c g k g K
# 2 d h l H L
# key1_x key2 key3 key1_y key4
# 0 a e i a i
# 1 b f j B j
# 2 c g k c K
# key1 key2 key3 key4
# 0 a e i i
# 1 c g k K
# key1 key2 key3 key4
# 0 a e i i
# 1 c g k K
参数on演示
how:指定合并方式,如果不指定默认为inner
inner相当于sql中的=,outer相当于sql中的full join,left相当于sql中的left join,right相当于sql中的right join;index重新生成为从0开始的整数。
对于outer、left、right来说可能会出现缺失值,全部以NaN填充。
df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n',])
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H'],'key4':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,how='inner')) #默认方式,取交集
print(pd.merge(df1,df2,how='outer')) #取并集
print(pd.merge(df1,df2,how='left')) #以左边为参考,即保留左边所有行
print(pd.merge(df1,df2,how='right')) #以右边为参考,即保留右边所有行
# key1 key2 key3
# k a e i
# l b f j
# m c g k
# n d h l
# key1 key2 key4
# p a e i
# q B f j
# u c g K
# v d H L
# key1 key2 key3 key4
# 0 a e i i
# 1 c g k K
# key1 key2 key3 key4
# 0 a e i i
# 1 b f j NaN
# 2 c g k K
# 3 d h l NaN
# 4 B f NaN j
# 5 d H NaN L
# key1 key2 key3 key4
# 0 a e i i
# 1 b f j NaN
# 2 c g k K
# 3 d h l NaN
# key1 key2 key3 key4
# 0 a e i i
# 1 c g k K
# 2 B f NaN j
# 3 d H NaN L
参数how演示
left_on和right_on:默认都为False,但是如果两个DataFrame没有相同的column而又需要对它们的按列合并,则需要使用left_on和right_on分别指明两边的参考列;index重新生成为从0开始的整数。
但是left_on和right_on不是必须成对出现,下面关于left_index和right_index会涉及到。
df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n'])
df2 = pd.DataFrame({'key4':['a','B','c','d'],'key5':['e','f','g','H'],'key6':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
# print(pd.merge(df1,df2,df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n'])
df2 = pd.DataFrame({'key4':['a','B','c','d'],'key5':['e','f','g','H'],'key6':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
# print(pd.merge(df1,df2,left_on='key1',right_on='key4'))
# key1 key2 key3
# k a e i
# l b f j
# m c g k
# n d h l
# key4 key5 key6
# p a e i
# q B f j
# u c g K
# v d H L
# key1 key2 key3 key4 key5 key6
# 0 a e i a e i
# 1 c g k c g K
# 2 d h l d H L='key1',right_on='key4'))
# key1 key2 key3
# k a e i
# l b f j
# m c g k
# n d h l
# key4 key5 key6
# p a e i
# q B f j
# u c g K
# v d H L
# key1 key2 key3 key4 key5 key6
# 0 a e i a e i
# 1 c g k c g K
# 2 d h l d H L
参数left_on和right_on演示
left_index和right_index:默认都为False,如果需要按索引进行合并,则需要使用left_index和right_index指明以index为参考。(on、left_on、right_on都是指定以column为参考)
如果使用了left_index或者right_index,必须指明另一方的参考键。
结果除了包含两个DataFrame的所有列,还会生成一个新的列,新列即以指定的两个参考进行合并后的结果。
如果是left_on = '**' 和right_index = True或者left_index = True 和right_on = '**',index取on所在的一方,如果是left_index = True和right_index = True,取两者相同的即可。
df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h']},index=['k','l','m','n'])
df2 = pd.DataFrame({'key1':['k',6,'l']},index=['a','m','c'])
print(df1)
print(df2)
print(pd.merge(df1,df2,left_on='key1',right_index=True)) #index取df1的
print(pd.merge(df1,df2,left_index=True,right_on='key1')) #index取df2的
print(pd.merge(df1,df2,left_index=True,right_index=True)) #index取两者交集
# key1 key2
# k a e
# l b f
# m c g
# n d h
# key1
# a k
# m 6
# c l
# key1 key1_x key2 key1_y
# k a a e k
# m c c g l
# key1 key1_x key2 key1_y
# a k a e k
# c l b f l
# key1_x key2 key1_y
# m c g 6
参数left_index和right_index演示
sort:结果是否按照参考进行排序,默认不排序;数字按照大小排序,字符串按照A-Za-z排序。
merge结果的显示顺序默认是按照df1、df2的行顺序进行显示,
df1 = pd.DataFrame({'key1':['d','a','c','B'],'key2':[3,6,1,8]},index=['k','l','m','n'])
df2 = pd.DataFrame({'key1':['c','B','a','d'],'key2':[3,8,2,1]},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,on='key2',))
print(pd.merge(df1,df2,on='key1',sort=True))
# key1 key2
# k d 3
# l a 6
# m c 1
# n B 8
# key1 key2
# p c 3
# q B 8
# u a 2
# v d 1
# key1_x key2 key1_y
# 0 d 3 c
# 1 c 1 d
# 2 B 8 B
# key1 key2_x key2_y
# 0 B 8 8
# 1 a 6 2
# 2 c 1 3
# 3 d 3 1
参数sort演示
pandas自带的排序方法df.sort_index()、df.sort_values('column')
suffixes:如果两者相同的column未被指定为参考列,那么结果中这两个相同的column名称会被加上后缀,默认为左右分别为_x和_y
df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h']},index=['k','l','m','n',])
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H']},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,on='key1'))
print(pd.merge(df1,df2,on='key2',suffixes=('_df1','_df2')))
# key1 key2_x key2_y
# 0 a e e
# 1 c g g
# 2 d h H
# key1_df1 key2 key1_df2
# 0 a e a
# 1 b f B
# 2 c g c
参数suffixed演示
二、join
join是默认按照index、以left方式实现两个DataFrame的合并,即默认用法相当于merge的pd.merge(df1,df2,how = 'left',left_index = True,right_index = True),缺失值默认为NaN
df1.join(df2, on=None, how='left', lsuffix='', rsuffix='',sort=False)
由于join的lsuffix和rsuffix默认值为空,因此如果两者有相同的column,一定要手动指定这两个参数,否则会报错。
join也可以通过on指定前面的DataFrame以column为参考与后面的index关联实现合并,即相当于merge的pd.merge(df1,df2,how = 'left',left_on ='**',right_index = True)。
index重新生成为从0开始的整数。
df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':[1,2,3,4]})
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key3':['e','f','g','H']})
print(df1)
print(df2)
print(df1.join(df2,on='key2',lsuffix='_df1',rsuffix='_df2'))
# key1 key2
# 0 a 1
# 1 b 2
# 2 c 3
# 3 d 4
# key1 key3
# 0 a e
# 1 B f
# 2 c g
# 3 d H
# key1_df1 key2 key1_df2 key3
# 0 a 1 B f
# 1 b 2 c g
# 2 c 3 d H
# 3 d 4 NaN NaN
join演示
三、concat
上述merge和join都是指定了column或者index为参考对两个DataFrame进行合并,concat是单纯的对DataFrame进行堆叠,并且空值填充为NaN。
concat可一次实现对多个pandas对象的堆叠,默认是对所有列在垂直方向进行堆叠、index为原来各自的索引。
concat( [obj1, obj2, obj3], axis=0, join="outer", join_axes=None, ignore_index=False, keys=None,
levels=None, names=None, verify_integrity=False, sort=None, copy=True)
如果是在水平方向进行堆叠,需要指定axis=1,如果合并后有相同列名称,可通过add_prefix或者add_suffix为其中一个添加名称后缀。
s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(s1)
print(s2)
print(pd.concat([s1,s2]))
print(pd.concat([s1,s2],axis=1,sort=False))
# a 1
# b 2
# c 3
# Name: s1, dtype: int64
# c 3
# x 4
# y w
# Name: s2, dtype: object
# a 1
# b 2
# c 3
# c 3
# x 4
# y w
# dtype: object
# s1 s2
# a 1.0 NaN
# b 2.0 NaN
# c 3.0 3
# x NaN 4
# y NaN w
参数axis演示
join表示堆叠方式,默认为outer,只有outer和inner方式,inner表示只对相同列进行堆叠。
s1 = pd.DataFrame([[1,2,3],[4,5,6]],columns=['a','b','c'])
s2 = pd.DataFrame([[3,4,'w'],[5,6,'x']],columns=['a','b','d'])
print(s1)
print(s2)
print(pd.concat([s1,s2]))
print(pd.concat([s1,s2],join="inner"))
# a b c
# 0 1 2 3
# 1 4 5 6
# a b d
# 0 3 4 w
# 1 5 6 x
# a b c d
# 0 1 2 3.0 NaN
# 1 4 5 6.0 NaN
# 0 3 4 NaN w
# 1 5 6 NaN x
# a b
# 0 1 2
# 1 4 5
# 0 3 4
# 1 5 6
参数join演示
ignore_index表示是否保留原对象的index,默认保留,True表示结果的index为从0开始的整数。
s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(pd.concat([s1,s2]))
print(pd.concat([s1,s2],ignore_index=True))
# a 1
# b 2
# c 3
# c 3
# x 4
# y w
# dtype: object
# 0 1
# 1 2
# 2 3
# 3 3
# 4 4
# 5 w
# dtype: object
参数ignore_index演示
join_axes指定结果显示的行索引
s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(pd.concat([s1,s2],axis=1))
print(pd.concat([s1,s2],axis=1,join_axes=[['a','c']]))
# s1 s2
# a 1.0 NaN
# b 2.0 NaN
# c 3.0 3
# x NaN 4
# y NaN w
# s1 s2
# a 1 NaN
# c 3 3
参数join_axes演示
对于Seris来说,默认按照竖直方向堆叠,如果再指定keys,则会形成一个层次索引。
如果在设置axis=1的情况下即按照水平方向进行堆叠,再指定keys,则keys的值会成为column。
s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(pd.concat([s1,s2])) #竖直方向堆叠
print(pd.concat([s1,s2],keys=['s1','s2'])) #竖直方向堆叠,并形成一个层次索引
print(pd.concat([s1,s2],axis=1,keys=['s1','s2'])) #水平方向堆叠,keys的值为column
# a 1
# b 2
# c 3
# c 3
# x 4
# y w
# dtype: object
# s1 a 1
# b 2
# c 3
# s2 c 3
# x 4
# y w
# dtype: object
# s1 s2
# a 1.0 NaN
# b 2.0 NaN
# c 3.0 3
# x NaN 4
# y NaN w
参数keys演示
四、替换空值combine_first
在相同index和column的位置,用一个对象的值去替换另一个对象的空值NaN。
df1.combine_forst(df2),如果df2有不在df1中的index和column,直接追加上去。
df1 = pd.DataFrame([[1,np.nan,3],[np.nan,5,6]],columns=['a','b','c'])
df2 = pd.DataFrame([[3,4,'w'],[5,6,'x'],[7,8,9]],columns=['a','b','d'])
print(df1)
print(df2)
print(df1.combine_first(df2)) #对于index为0和1,在对应column位置使用df2的值替换df1的空值
#df2中的index=2和column='d'不在df1中,结果保留这一行和这里一列,
# a b c
# 0 1.0 NaN 3
# 1 NaN 5.0 6
# a b d
# 0 3 4 w
# 1 5 6 x
# 2 7 8 9
# a b c d
# 0 1.0 4.0 3.0 w
# 1 5.0 5.0 6.0 x
# 2 7.0 8.0 NaN 9
combine_first演示
五、更新update
在相同index和column的位置,使用一个对象的值去更新原对象的值,该方法没有返回值,直接修改原对象。
df1.update(df2),更新df1,结果只包含原对象的行和列。
df1 = pd.DataFrame([[1,np.nan,3],[np.nan,5,6]],columns=['a','b','c'])
df2 = pd.DataFrame([[3,4,'w'],[5,6,'x'],[7,8,9]],columns=['a','b','d'])
df1.update(df2) #没有返回值,直接打印结果为none,且df2中的第3行和d列不追加到df1
print(df1)
# a b c
# 0 3.0 4.0 3
# 1 5.0 6.0 6
update演示
六、去重duplicate与drop_duplicates
duplicate()结果是一个值为布尔的Seris,通过obj[ df.duplicated()==False ]来取出Seris和DataFrame中的重复值、行,新结果的index为False对应的索引。
对于Seris,从第一个值开始判断,如果元素第一次出现,则duplicate后的值为True,否则为False
对应于DataFrame,从第一行开始判断,如果行的内容第一次出现(要求行内元素顺序一致),则duplicate后的值为True,否则为False。如
s = pd.Series([1,2,2,1,3,3])
print(s.duplicated())
print(s[s.duplicated()==False])
print('----------------')
df = pd.DataFrame([[1,2,3],[4,5,6],[1,3,2],[4,5,6],[7,8,9]])
print(df.duplicated()) #[1,2,3]和[1,3,2]不重复
print(df[df.duplicated()==False])
# 0 False
# 1 False
# 2 True
# 3 True
# 4 False
# 5 True
# dtype: bool
# 0 1
# 1 2
# 4 3
# dtype: int64
# ----------------
# 0 False
# 1 False
# 2 False
# 3 True
# 4 False
# dtype: bool
# 0 1 2
# 0 1 2 3
# 1 4 5 6
# 2 1 3 2
# 4 7 8 9
duplicated去重
drop_duplicates( )删除重复的元素,默认生成新的结果不修改原对象,如果添加参数inplace=True则直接修改原对象。新结果的index为元素第一次出现时对应的索引
s = pd.Series([1,2,2,1,3,3])
print(s.drop_duplicates())
df = pd.DataFrame([[1,2,3],[4,5,6],[1,3,2],[4,5,6],[7,8,9]])
df.drop_duplicates(inplace=True)
print(df)
# 0 1
# 1 2
# 4 3
# dtype: int64
# 0 1 2
# 0 1 2 3
# 1 4 5 6
# 2 1 3 2
# 4 7 8 9
drop_duplicates去重
七、替换replace
replace('原元素','新元素')将原元素替换成新元素
如果要同时替换多个元素,用列表表示即可;如果要将不同的元素替换成不同的内容,使用字典。
s = pd.Series(list('abcafc'))
print(s.replace('a','A')) #将每个a替换成A
print(s.replace(['a','b'],'W')) #将所有a、b替换成W
print(s.replace({'a':'A','f':'F'})) #将a替换成A,f替换成F df = pd.DataFrame([[1,2,3],[4,5,6],[2,5,8]])
print(df.replace(2,'a')) #将2替换成a
replace演示
pandas之DataFrame合并merge的更多相关文章
- pandas 7 合并 merge 水平合并,数据会变宽
pd.merge( df1, df2, on=['key1', 'key2'], left_index=True, right_index=True, how=['left', 'right', 'o ...
- 【转】Pandas学习笔记(六)合并 merge
Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...
- 利用Python进行数据分析(12) pandas基础: 数据合并
pandas 提供了三种主要方法可以对数据进行合并: pandas.merge()方法:数据库风格的合并: pandas.concat()方法:轴向连接,即沿着一条轴将多个对象堆叠到一起: 实例方法c ...
- python 数据处理学习pandas之DataFrame
请原谅没有一次写完,本文是自己学习过程中的记录,完善pandas的学习知识,对于现有网上资料的缺少和利用python进行数据分析这本书部分知识的过时,只好以记录的形势来写这篇文章.最如果后续工作定下来 ...
- Spark与Pandas中DataFrame对比
Pandas Spark 工作方式 单机single machine tool,没有并行机制parallelism不支持Hadoop,处理大量数据有瓶颈 分布式并行计算框架,内建并行机制paral ...
- Pandas之DataFrame——Part 3
''' [课程2.] 数值计算和统计基础 常用数学.统计方法 ''' # 基本参数:axis.skipna import numpy as np import pandas as pd df = pd ...
- Spark与Pandas中DataFrame对比(详细)
Pandas Spark 工作方式 单机single machine tool,没有并行机制parallelism不支持Hadoop,处理大量数据有瓶颈 分布式并行计算框架,内建并行机制paral ...
- python dataframe 在merge时 产生笛卡尔积
在pandas中,concat, merge, join的使用方法可以参考以下资料: http://blog.csdn.net/stevenkwong/article/details/52528616 ...
- [译]从列表或字典创建Pandas的DataFrame对象
原文来源:http://pbpython.com/pandas-list-dict.html 介绍 每当我使用pandas进行分析时,我的第一个目标是使用众多可用选项中的一个将数据导入Pandas的D ...
随机推荐
- python利用列表文件遍历
关键词:文件遍历/列表 思路:先制作目标文件列表(txt/csv...均可),再逐行读取列表文件 1. 制作列表 linux 终端输入:# find ./abc -type f > list.t ...
- java中的四种访问权限是?
1.私有权限(private) private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类).被private修饰的成员,只能在定义它们的类中使用,在其他类中不能调用. ...
- 二.4vue展示用户数据及用户组操作以及给用户组添加额外字段
一.用户列表 1.新建(1)views/users/index.vue: <template> <div class="user-list-container"& ...
- 运行python出现 SyntaxError: Non-ASCII character '\xe6' in file /Users/finup/Documents/python_project/test.py 解决办法
使用pycharm运行程序时出现以下错误 这个错误主要是由于python2的编码默认是ASCII,你的文件里有中文就必须要用utf-8编码,只要在文件需要在文件开头标注 #coding=utf-8如下 ...
- 关于前端数据&逻辑的思考
最近重构了一个项目,一个基于redux模型的react-native项目,目标是在混乱的代码中梳理出一个清晰的结构来,为了实现这个目标,首先需要对项目的结构做分层处理,将各个逻辑分离出来,这里我是基于 ...
- css3动画讲解,关于css3的@keyframes和animation
通过css3我们可以创建动画,它能取代gif图片.Flash.Js动画等,css3的animation动画是应用在html的DOM元素上的,通过样式来实现的. @keyframes 规则 @Keyfr ...
- 状压DP之排列perm
题目 [SCOI2007]排列 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. 输 ...
- POJ3057 Evacuation 二分图匹配+最短路
POJ3057 Evacuation 二分图匹配+最短路 题目描述 Fires can be disastrous, especially when a fire breaks out in a ro ...
- opencv3.4.9 + armv7 + arm-linux-gnueabihf交叉编译
使用CMake指定交叉编译链会有很多报错,原因可能是其找交叉编译的库或这头文件会自动链接到本地的库或者头文件. 可以使用Qt设置好交叉编译环境后,将CMakeLists.txt文件放入,直接编译通过即 ...
- Quartz.Net 任务调度
基于ASP.NET MVC(C#)和Quartz.Net组件实现的定时执行任务调度 在之前的文章<推荐一个简单.轻量.功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentSch ...