pandas dataframe的合并实现(append, merge, concat)
创建2个DataFrame:
>>>df1=pd.DataFrame(np.ones((4,4))*1,columns=list('DCBA'),index=list('4321')) >>>df2=pd.DataFrame(np.ones((4,4))*2,columns=list('FEDC'),index=list('6543')) >>>df3=pd.DataFrame(np.ones((4,4))*3,columns=list('FEBA'),index=list('6521')) >>>df1 DCBA 41.01.01.01.0 31.01.01.01.0 21.01.01.01.0 11.01.01.01.0 >>>df2 FEDC 62.02.02.02.0 52.02.02.02.0 42.02.02.02.0 32.02.02.02.0 >>>df3 FEBA 63.03.03.03.0 53.03.03.03.0 23.03.03.03.0 13.03.03.03.0
1,concat
pd.concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False, keys=None,levels=None,names=None,verify_integrity=False, copy=True)
示例:
>>>pd.concat([df1,df2]) ABCDEF 41.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN 6NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 4NaNNaN2.02.02.02.0 3NaNNaN2.02.02.02.0
1.1,axis
默认值:axis=0
axis=0:竖方向(index)合并,合并方向index作列表相加,非合并方向columns取并集
axis=1:横方向(columns)合并,合并方向columns作列表相加,非合并方向index取并集
axis=0:
>>>pd.concat([df1,df2],axis=0) ABCDEF 41.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN 6NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 4NaNNaN2.02.02.02.0 3NaNNaN2.02.02.02.0
axis=1:
>>>pd.concat([df1,df2],axis=1) DCBAFEDC 11.01.01.01.0NaNNaNNaNNaN 21.01.01.01.0NaNNaNNaNNaN 31.01.01.01.02.02.02.02.0 41.01.01.01.02.02.02.02.0 5NaNNaNNaNNaN2.02.02.02.0 6NaNNaNNaNNaN2.02.02.02.0
备注:原df中,取并集的行/列名称不能有重复项,即axis=0时columns不能有重复项,axis=1时index不能有重复项:
>>>df1.columns=list('DDBA') >>>pd.concat([df1,df2],axis=0) ValueError:Planshapesarenotaligned
1.2,join
默认值:join=‘outer'
非合并方向的行/列名称:取交集(inner),取并集(outer)。
axis=0时join='inner',columns取交集:
>>>pd.concat([df1,df2],axis=0,join='inner') DC 41.01.0 31.01.0 21.01.0 11.01.0 62.02.0 52.02.0 42.02.0 32.02.0
axis=1时join='inner',index取交集:
>>>pd.concat([df1,df2],axis=1,join='inner') DCBAFEDC 41.01.01.01.02.02.02.02.0 31.01.01.01.02.02.02.02.0
1.3,join_axes
默认值:join_axes=None,取并集
合并后,可以设置非合并方向的行/列名称,使用某个df的行/列名称
axis=0时join_axes=[df1.columns],合并后columns使用df1的:
>>>pd.concat([df1,df2],axis=0,join_axes=[df1.columns]) DCBA 41.01.01.01.0 31.01.01.01.0 21.01.01.01.0 11.01.01.01.0 62.02.0NaNNaN 52.02.0NaNNaN 42.02.0NaNNaN 32.02.0NaNNaN
axis=1时axes=[df1.index],合并后index使用df2的:
pd.concat([df1,df2],axis=1,join_axes=[df1.index]) DCBAFEDC 41.01.01.01.02.02.02.02.0 31.01.01.01.02.02.02.02.0 21.01.01.01.0NaNNaNNaNNaN 11.01.01.01.0NaNNaNNaNNaN
同时设置join和join_axes的,以join_axes为准:
>>>pd.concat([df1,df2],axis=0,join='inner',join_axes=[df1.columns]) DCBA 41.01.01.01.0 31.01.01.01.0 21.01.01.01.0 11.01.01.01.0 62.02.0NaNNaN 52.02.0NaNNaN 42.02.0NaNNaN 32.02.0NaNNaN
1.4,ignore_index
默认值:ignore_index=False
合并方向是否忽略原行/列名称,而采用系统默认的索引,即从0开始的int。
axis=0时ignore_index=True,index采用系统默认索引:
>>>pd.concat([df1,df2],axis=0,ignore_index=True) ABCDEF 01.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 4NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 6NaNNaN2.02.02.02.0 7NaNNaN2.02.02.02.0
axis=1时ignore_index=True,columns采用系统默认索引:
>>>pd.concat([df1,df2],axis=1,ignore_index=True) 01234567 11.01.01.01.0NaNNaNNaNNaN 21.01.01.01.0NaNNaNNaNNaN 31.01.01.01.02.02.02.02.0 41.01.01.01.02.02.02.02.0 5NaNNaNNaNNaN2.02.02.02.0 6NaNNaNNaNNaN2.02.02.02.0
1.5,keys
默认值:keys=None
可以加一层标签,标识行/列名称属于原来哪个df。
axis=0时设置keys:
>>>pd.concat([df1,df2],axis=0,keys=['x','y']) ABCDEF x41.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN y6NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 4NaNNaN2.02.02.02.0 3NaNNaN2.02.02.02.0
axis=1时设置keys:
>>>pd.concat([df1,df2],axis=1,keys=['x','y']) xy DCBAFEDC 11.01.01.01.0NaNNaNNaNNaN 21.01.01.01.0NaNNaNNaNNaN 31.01.01.01.02.02.02.02.0 41.01.01.01.02.02.02.02.0 5NaNNaNNaNNaN2.02.02.02.0 6NaNNaNNaNNaN2.02.02.02.0
也可以传字典取代keys:
>>>pd.concat({'x':df1,'y':df2},axis=0) ABCDEF x41.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN y6NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 4NaNNaN2.02.02.02.0 3NaNNaN2.02.02.02.0
1.6,levels
默认值:levels=None
明确行/列名称取值范围:
>>>pd.concat([df1,df2],axis=0,keys=['x','y'],levels=[['x','y','z','w']]) >>>df.index.levels [['x','y','z','w'],['1','2','3','4','5','6']]
1.7,sort
默认值:sort=True,提示新版本会设置默认为False,并取消该参数
但0.22.0中虽然取消了,还是设置为True
非合并方向的行/列名称是否排序。例如1.1中默认axis=0时columns进行了排序,axis=1时index进行了排序。
axis=0时sort=False,columns不作排序:
>>>pd.concat([df1,df2],axis=0,sort=False) DCBAFE 41.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN 62.02.0NaNNaN2.02.0 52.02.0NaNNaN2.02.0 42.02.0NaNNaN2.02.0 32.02.0NaNNaN2.02.0
axis=1时sort=False,index不作排序:
>>>pd.concat([df1,df2],axis=1,sort=False) DCBAFEDC 41.01.01.01.02.02.02.02.0 31.01.01.01.02.02.02.02.0 21.01.01.01.0NaNNaNNaNNaN 11.01.01.01.0NaNNaNNaNNaN 6NaNNaNNaNNaN2.02.02.02.0 5NaNNaNNaNNaN2.02.02.02.0
1.8,concat多个DataFrame
>>>pd.concat([df1,df2,df3],sort=False,join_axes=[df1.columns]) DCBA 41.01.01.01.0 31.01.01.01.0 21.01.01.01.0 11.01.01.01.0 62.02.0NaNNaN 52.02.0NaNNaN 42.02.0NaNNaN 32.02.0NaNNaN 6NaNNaN3.03.0 5NaNNaN3.03.0 2NaNNaN3.03.0 1NaNNaN3.03.0
2,append
append(self,other,ignore_index=False,verify_integrity=False)
竖方向合并df,没有axis属性
不会就地修改,而是会创建副本
示例:
>>>df1.append(df2)#相当于pd.concat([df1,df2]) ABCDEF 41.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN 6NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 4NaNNaN2.02.02.02.0 3NaNNaN2.02.02.02.0
2.1,ignore_index属性
>>>df1.append(df2,ignore_index=True) ABCDEF 01.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 4NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 6NaNNaN2.02.02.02.0 7NaNNaN2.02.02.02.0
2.2,append多个DataFrame
和concat相同,append也支持append多个DataFrame
>>>df1.append([df2,df3],ignore_index=True) ABCDEF 01.01.01.01.0NaNNaN 11.01.01.01.0NaNNaN 21.01.01.01.0NaNNaN 31.01.01.01.0NaNNaN 4NaNNaN2.02.02.02.0 5NaNNaN2.02.02.02.0 6NaNNaN2.02.02.02.0 7NaNNaN2.02.02.02.0 83.03.0NaNNaN3.03.0 93.03.0NaNNaN3.03.0 103.03.0NaNNaN3.03.0 113.03.0NaNNaN3.03.0
3,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=pd.DataFrame({'A':['a0','a1','a2','a3'], 'B':['b0','b1','b2','b3'], 'k1':['x','x','y','y']}) >>>right=pd.DataFrame({'C':['c1','c2','c3','c4'], 'D':['d1','d2','d3','d4'], 'k1':['y','y','z','z']}) >>>left ABk1 0a0b0x 1a1b1x 2a2b2y 3a3b3y >>>right CDk1 0c1d1y 1c2d2y 2c3d3z 3c4d4z
对df1和df2进行merge:
>>>pd.merge(left,right) ABk1CD 0a2b2yc1d1 1a2b2yc2d2 2a3b3yc1d1 3a3b3yc2d2
可以看到只有df1和df2的key1=y的行保留了下来,即默认合并后只保留有共同列项并且值相等行(即交集)。
本例中left和right的k1=y分别有2个,最终构成了2*2=4行。
如果没有共同列会报错:
>>>delleft['k1'] >>>pd.merge(left,right) pandas.errors.MergeError:Nocommoncolumnstoperformmergeon
3.1,on属性
新增一个共同列,但没有相等的值,发现合并返回是空列表,因为默认只保留所有共同列都相等的行:
>>>left['k2']=list('1234') >>>right['k2']=list('5678') >>>pd.merge(left,right) EmptyDataFrame Columns:[B,A,k1,k2,F,E] Index:[]
可以指定on,设定合并基准列,就可以根据k1进行合并,并且left和right共同列k2会同时变换名称后保留下来:
>>>pd.merge(left,right,on='k1') ABk1k2_xCDk2_y 0a2b2y3c1d15 1a2b2y3c2d26 2a3b3y4c1d15 3a3b3y4c2d26
默认值:on的默认值是所有共同列,本例为:on=['k1','k2']
3.2,how属性
how取值范围:'inner','outer','left','right'
默认值:how='inner'
‘inner':共同列的值必须完全相等:
>>>pd.merge(left,right,on='k1',how='inner') ABk1k2_xCDk2_y 0a2b2y3c1d15 1a2b2y3c2d26 2a3b3y4c1d15 3a3b3y4c2d26
‘outer':共同列的值都会保留,left或right在共同列上的差集,会对它们的缺失列项的值赋上NaN:
>>>pd.merge(left,right,on='k1',how='outer') ABk1k2_xCDk2_y 0a0b0x1NaNNaNNaN 1a1b1x2NaNNaNNaN 2a2b2y3c1d15 3a2b2y3c2d26 4a3b3y4c1d15 5a3b3y4c2d26 6NaNNaNzNaNc3d37 7NaNNaNzNaNc4d48
‘left':根据左边的DataFrame确定共同列的保留值,右边缺失列项的值赋上NaN:
pd.merge(left,right,on='k1',how='left') ABk1k2_xCDk2_y 0a0b0x1NaNNaNNaN 1a1b1x2NaNNaNNaN 2a2b2y3c1d15 3a2b2y3c2d26 4a3b3y4c1d15 5a3b3y4c2d26
‘right':根据右边的DataFrame确定共同列的保留值,左边缺失列项的值赋上NaN:
>>>pd.merge(left,right,on='k1',how='right') ABk1k2_xCDk2_y 0a2b2y3c1d15 1a3b3y4c1d15 2a2b2y3c2d26 3a3b3y4c2d26 4NaNNaNzNaNc3d37 5NaNNaNzNaNc4d48
3.3,indicator
默认值:indicator=False,不显示合并方式
设置True表示显示合并方式,即left/right/both:
>>>pd.merge(left,right,on='k1',how='outer',indicator=True) ABk1k2_xCDk2_y_merge 0a0b0x1NaNNaNNaNleft_only 1a1b1x2NaNNaNNaNleft_only 2a2b2y3c1d15both 3a2b2y3c2d26both 4a3b3y4c1d15both 5a3b3y4c2d26both 6NaNNaNzNaNc3d37right_only 7NaNNaNzNaNc4d48right_only
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。