Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数

目录

1 pandas.merge

1.1 merge函数的语法

 1.2 单一键上合并

1.2.1 key名相同

 1.2.2 两者key名不同

1.3 多个键上合并

1.4 连接键key之外,合并数据中两者存在重复列名

1.5 索引上的合并

1.5.1 使用单方DataFrame索引

1.5.2 使用双方DataFrame索引

1.6 层次化索引

2 Pandas.concat

2.1 concat()函数语法

2.2 不同轴向上合并

2.2.1 axis=0轴上合并

2.2.2 axis=1轴上合并

2.3 设置其他轴上索引

2.4 当传入对象obj为字典

2.5 管理分层索引

3 pandas.DataFrame.join

3.1 join()函数语法

3.2 两个DataFrame连接

3.3 多个DataFrame连接

4 combine_first 

4.1 pandas.Series.combine_first

4.1.1 Series.combine_first 函数语法

4.1.2 Series.combine_first 实例

4.2 pandas.DataFrame.combine_first

4.2.1 DataFrame.combine_first函数语法

4.2.2 DataFrame.combine_first 实例

5 小结


在数据分析和建模的工作中,需要对数据进行规整:加载、清理、转换以及重塑等。

本文总结梳理Python标准库和Pandas用于数据集合并的两种方法:pandas.merge,pandas.concat,pandas.DataFrame.join,combine_first。

参考书籍《利用Python进行数据分析》

1 pandas.merge

数据集的merge合并是通过一个或多个键key将行链接起来。

1.1 merge函数的语法

pandas.merge(leftrighthow='inner'on=Noneleft_on=Noneright_on=Noneleft_index=Falseright_index=Falsesort=Falsesuffixes=('_x''_y')copy=Trueindicator=Falsevalidate=None)

主要参数:

参数 说明
left 参与合并的左侧DataFrame
right 参与合并的右侧DataFrame
how “inner”,“outer”,“left”,“right”其中之一。默认为“inner”
on

用于连接的列名。必须存在于左右两个DataFrame对象中。

如果未指定,且其他连接键也未指定,则以left和right列名的交集作为连接键

left_on 左侧DataFrame中用作连接键的列
right_on 右侧DataFrame中用作连接键的列
left_index 将左侧的行索引用作其连接键
right_index 将右侧的行索引用作其连接键
sort

根据连接键对合并后的数据进行排序,默认为False,按照合并的方式how进行排序。

如果为True,按照连接键名的字母顺序排序

suffixes

字符串值元祖,用于追加到重叠列名的末尾,默认为('_x','_y')。

例如,如果左右两个DataFrame对象都有'data',则结果中就会出现'data_x' 和 'data_y'

copy 设置会False,可以在某些特殊情况下避免将数据复制到结果数据中。默认总是复制。

 1.2 单一键上合并

1.2.1 key名相同

 

import pandas as pd

import numpy as np

df1 = pd.DataFrame({"key":["b","b","a","c","a","a","b"],"data1":range(7)})

df2 = pd.DataFrame({"key":["a","b","d"],"data2":range(3)})

pd.merge(df1,df2, on="key") # merge默认的方式是inner

df1:                                  df2:                                                 pd.merge(df1,df2, on="key")

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第1张图片            Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第2张图片                                           Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第3张图片

 上述是一种多对一的合并。函数中如果没有指定on="key"也是可以的,默认选择两个dataframe中相同的key来连接。

但,建议还是要显式表达出来。

 1.2.2 两者key名不同

这种情况,可以用left_on 和 right_on 分别指定。

df3 = pd.DataFrame({"lkey":["b","b","a","c","a","a","b"],"data1":range(7)})

df4 = pd.DataFrame({"rkey":["a","b","d"],"data2":range(3)})

pd.merge(df3,df4,left_on="lkey",right_on="rkey")

df3:                                  df4:                                                 merge函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第4张图片          Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第5张图片                               Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第6张图片

默认merge连接方式为inner,即求df3和df4的交集,所以c,d对应的数据在上述结果中消失了。并集,可以设置参数how='outer'。

1.3 多个键上合并

多个键上合并,需要设置参数on,传入一个列名组成的列表做为参数即可。

left = pd.DataFrame({"key1":['foo','foo','bar'],"key2":['one','two','one'],'lval':[1,2,3]})

right = pd.DataFrame({"key1":['foo','foo','bar','bar'],"key2":['one','one','one','two'],'rval':[4,5,6,7]})

pd.merge(left,right,on=["key1","key2"],how="outer")

 left:                                         right:                                                 merge函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第7张图片           Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第8张图片                          Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第9张图片

 

1.4 连接键key之外,合并数据中两者存在重复列名

如果将上述创建的left表和right表,仅按照key1进行合并,两者都存在key2这一相同的列名,如何在合并后的dataframe中加以区分呢?

merge有一个很实用的suffixes参数,默认是在重复的列名后面加上(‘_x’, ‘_y’)。

left = pd.DataFrame({"key1":['foo','foo','bar'],"key2":['one','two','one'],'lval':[1,2,3]})

right = pd.DataFrame({"key1":['foo','foo','bar','bar'],"key2":['one','one','one','two'],'rval':[4,5,6,7]})

pd.merge(left,right,on=["key1"])

left:                                         right:                                 merge函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第10张图片           Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第11张图片         Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第12张图片

如果要自己设计后缀名,可以单独设置suffixes的参数,suffixes=("_left","_right")。

left = pd.DataFrame({"key1":['foo','foo','bar'],"key2":['one','two','one'],'lval':[1,2,3]})

right = pd.DataFrame({"key1":['foo','foo','bar','bar'],"key2":['one','one','one','two'],'rval':[4,5,6,7]})

pd.merge(left,right,on='key1',suffixes=("_left","_right"))  #设置自己命名的后缀

left:                                         right:                                merge函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第13张图片           Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第14张图片           Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第15张图片

1.5 索引上的合并

当DataFrame合并的连接键,为某一DataFrame或两者DataFrame索引index的时候,可以设置merge函数的left_index=True或者right_index=True,或两者都设置为True。设置为True的DataFrame将其索引作为连接键。

1.5.1 使用单方DataFrame索引

# 用left1的列名、right1的索引左右连接件键

left1 = pd.DataFrame({"key":["a","b","a","a","b","c"],"value":range(6)})

right1 = pd.DataFrame({"group_val":[3.5,7]},index=["a","b"])

pd.merge(left1,right1,left_on="key",right_index=True)

left1:                                right1:                       merge函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第16张图片            Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第17张图片          Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第18张图片

1.5.2 使用双方DataFrame索引

合并时,同时使用双方的索引也是没有问题的。

left2 = pd.DataFrame([[1,2],[3,4],[5,6]],index=['a','c','e'],columns=['Ohio','Nevada'])

right2 = pd.DataFrame([[7,8],[9,10],[11,12],[13,14]],index=['b','c','d','e'],columns=['Missouri','Alabama'])

pd.merge(left2,right2,how='outer',left_index=True,right_index=True)

left2:                                         right2:                                           merge函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第19张图片            Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第20张图片            Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第21张图片

1.6 层次化索引

lefth = pd.DataFrame({"key1":['Ohio','Ohio','Ohio','Nevada','Nevada'],
                      'key2':[2000,2001,2002,2001,2002],
                      'data':np.arange(5)})

righth = pd.DataFrame(np.arange(12).reshape((6,2)),
                      index=[['Nevada','Nevada','Ohio','Ohio','Ohio','Ohio'],
                             [2001,2000,2000,2000,2001,2002]],
                      columns=['event1','event2'])

pd.merge(lefth,righth,left_on=['key1','key2'],right_index=True)

 遇到层次化索引,看起来有点复杂,请道理是一样的。对于多个key进行合并,以列表形式指明用于合并键的多个列即可。

lefth:                                         righth:                                              merge函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第22张图片     Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第23张图片       Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第24张图片

2 Pandas.concat

2.1 concat()函数语法

concat()函数可以用于多个对象之间的连接。

pandas.concat(objsaxis=0join='outer'join_axes=Noneignore_index=Falsekeys=Nonelevels=Nonenames=Noneverify_integrity=Falsesort=Nonecopy=True)

主要参数:

参数 说明
obj 参与连接的pandas对象的列表或字典。唯一必需的参数
axis 指明连接的轴向,默认为0
join “inner”,“outer”其中之一,默认为“outer”。指明其他轴向上的索引是按照交集(inner)还是并集(outer)进行合并
join_axes 指明用于其他n-1条轴的索引,不执行并集/交集运算
keys 与连接对象有关的值,用于形成连接轴向上的层次化索引。可以是任意值的列表或数组、元祖数组、数组列表(如果将levels设置成多级数组的话)
names 用于创建分层级别的名称,如果设置了keys和(或)levels的话
verify_integrity 检查结果对象新轴上的重复情况,如果发现则引发异常。默认(False)允许重复
ignore_index

不保留连接轴上的索引,产生一组新索引range(total_length)

2.2 不同轴向上合并

2.2.1 axis=0轴上合并

s1=pd.Series([0,1],index=['a','b'])
s2=pd.Series([2,3,4],index=['c','d','e'])
s3=pd.Series([5,6],index=['f','g'])
pd.concat([s1,s2,s3]) # 默认 axis = 0

s1                             s2                                   s3                                        concat函数作用后

       Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第25张图片                            Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第26张图片

以上调用concat函数将值和索引粘连在一起,默认在axis=0上工作,最终产生一个新的Series。

2.2.2 axis=1轴上合并

上述的s1,s2,s3如果在axis=1上合并,结果如何呢?

s1=pd.Series([0,1],index=['a','b'])
s2=pd.Series([2,3,4],index=['c','d','e'])
s3=pd.Series([5,6],index=['f','g'])
pd.concat([s1,s2,s3],axis=1)

s1                             s2                                   s3                                           concat函数作用后

       Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第27张图片                          Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第28张图片

从上述结果可以看出,concat函数默认的是外连接方式outer。在axis=1上工作,最终产生一个新的DataFrame。

合并时,没有对应值得位置,为NaN空值。

 

在axis=1的条件下,通过设置join='inner'参数,可以得到交集。

2.3 设置其他轴上索引

我们可以通过:

设置join_axes参数,来设置合并时在其他轴上的索引。如,下方按照行索引['a','c','b','e']进行合并,当索引为'c'和'e'时,没有对应的数值,为NaN空。

设置keys参数,来设置合并轴上的索引。如,下方代码将合并后列索引设置为"set1","set2"。

s1=pd.Series([0,1],index=['a','b'])
s4=pd.concat([s1*5,s3]) 
pd.concat([s1,s4],axis=1,join_axes=[['a','c','b','e']],keys=["set1","set2"])

s1                                                       s4                                           concat函数作用后

                         Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第29张图片                         Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第30张图片

2.4 当传入对象obj为字典

当concat函数传入的对象obj不是列表,而是字典形式时,字典的键将会被当做keys选项的值。

如下方代码,对象为字典{'level1':df1,'level2':df2}。'level1'和'level2'被当做合并后DataFrame的列的值。

df1 = pd.DataFrame(np.arange(6).reshape(3,2),index=['a','b','c'],columns=['one','two'])
df2 = pd.DataFrame(5+np.arange(4).reshape(2,2),index=['a','c'],columns=['three','four'])
pd.concat({'level1':df1,'level2':df2},axis=1)

df1                                               df2                                               concat函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第31张图片                     Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第32张图片                               Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第33张图片

2.5 管理分层索引

 同2.5节中代码一致,我们另外加上names参数设置,可以加入层次化的索引。效果参下图,增加了层次化索引'level','ord_num'。

df1 = pd.DataFrame(np.arange(6).reshape(3,2),index=['a','b','c'],columns=['one','two'])
df2 = pd.DataFrame(5+np.arange(4).reshape(2,2),index=['a','c'],columns=['three','four'])
pd.concat({'level1':df1,'level2':df2},axis=1,names=['level','ord_num'])

df1                                         df2                                        concat函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第34张图片           Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第35张图片              Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第36张图片

3 pandas.DataFrame.join

3.1 join()函数语法

join()函数可以方便地实现按索引合并,用于合并多个带有相同或相似索引的DataFrame对象,而不管它们之间是否有重叠的列。

DataFrame.join(otheron=Nonehow='left'lsuffix=''rsuffix=''sort=False)

用法:将当前DataFrame同参数对象other的连接。

我们称 .join 前面的数据框为calling frame 或者为caller。

主要参数:

参数 说明
other

参与连接的对象,可以是DataFrame,Series,或者为DataFrame的列表。

该对象的index应该同调用函数的calling frame的index相似。

如果传入的对象是Series,那么Series的name属性必须制定,用来作为合并后数据框中对应的列名。

如果传入DataFrame的列表,即为多个DataFrame的连接

on 调用join函数的对象calling frame的列或者index索引名
how

 {‘left’, ‘right’, ‘outer’, ‘inner’},其中之一,默认为“left”

left:  使用calling frame的索引(或者on参数上特别制定的列)

right:使用参数对象other的索引

outer:使用caling frame和参数对象other的全部索引,并按照字母顺序排序

inner:使用caling frame和参数对象other的共有索引,并按照calling frame中索引顺序排列

lsuffix 用于追加到重叠列名的末尾,添加在左侧calling frame的重复列名后
rsuffix 用于追加到重叠列名的末尾,添加在右侧other frame的重复列名后
sort

将合并后的数据框内容按照连接键的字母顺序排序。

如果sort 为False,连接键的顺序由连接方式how的类型来决定

3.2 两个DataFrame连接

left2 = pd.DataFrame([[1,2],[3,4],[5,6]],
                     index=['a','c','e'],
                     columns=['Ohio','Nevada'])
right2 = pd.DataFrame([[7,8],[9,10],[11,12],[13,14]],
                      index=['b','c','d','e'],
                      columns=['Missouri','Alabama'])
left2.join(right2)  # 默认为左连接

left2                                            right2                                      join函数左右后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第37张图片          Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第38张图片        Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第39张图片

 

3.3 多个DataFrame连接

对于简单的索引合并,我们还可想join传入一组DataFrame。

如3.2中的连接函数中,我们在传入一个DataFrame为another,join函数的参数为一组DataFrame组成的列表。

left2 = pd.DataFrame([[1,2],[3,4],[5,6]],
                     index=['a','c','e'],
                     columns=['Ohio','Nevada'])
right2 = pd.DataFrame([[7,8],[9,10],[11,12],[13,14]],
                      index=['b','c','d','e'],
                      columns=['Missouri','Alabama'])
another = pd.DataFrame([[7,8],[9,10],[11,12],[16,17]],index=['a','c','e','f'],
                      columns=['New York','Oregon'])
left2.join([right2,another],how='inner')

left2                                                    right2                                      

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第40张图片                Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第41张图片        

another                                                      join函数作用后

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第42张图片      Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第43张图片

这个例子多个对象直接的连接,连接方式为inner。我们同样可以用concat函数实现这个连接,结果是一样的。

left2 = pd.DataFrame([[1,2],[3,4],[5,6]],
                     index=['a','c','e'],
                     columns=['Ohio','Nevada'])
right2 = pd.DataFrame([[7,8],[9,10],[11,12],[13,14]],
                      index=['b','c','d','e'],
                      columns=['Missouri','Alabama'])
another = pd.DataFrame([[7,8],[9,10],[11,12],[16,17]],
                       index=['a','c','e','f'],
                      columns=['New York','Oregon'])
pd.concat([left2,right2,another],axis=1,join='inner')

但因为concat函数只有“inner”,“outer”两种,所以当连接方式为“left”,“right”时,concat函数就无法作用了。

4 combine_first 

对于有索引全部相同或者部分相同的两个数据集,可以使用combine_first实现数据的连接,同时可以进行数据对齐。

4.1 pandas.Series.combine_first

4.1.1 Series.combine_first 函数语法

Series.combine_first(other)

我们将 .combine_first 前面的Series称为 calling Series。

参数:other为用于结合的其他Series

作用:将两个Series中的值合并,优先选择calling Series中的值;如果calling Series中出现空值,用other中对应的值填充。

最终合并后的对象索引为两者索引的汇总。

4.1.2 Series.combine_first 实例

import pandas as pd
import numpy as np

a = pd.Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],index=['f','e','d','c','b','a'])
b = pd.Series(np.arange(len(a)),dtype=np.float64,index=['f','e','d','c','b','a'])
b[-1]=np.nan
b[:-2].combine_first(a[2:])

我们逐项列出上述代码相关对象:

a                                           a[2:]

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第44张图片             Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第45张图片

b                                         b[:-2]

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第46张图片               Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第47张图片

b[:-2].combine_first(a[2:]) 结果为:

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第48张图片

combine_first作用后的索引为b[:-2]和a[2:]两者索引的汇总。

b[:-2]中已有数值都非空,将保留;同时吸收其在a[2:]中没有的数据,即索引a,b对应的数据。

 

4.2 pandas.DataFrame.combine_first

4.2.1 DataFrame.combine_first函数语法

DataFrame.combine_first(other)

我们将 .combine_first 前面的Series称为 calling DataFrame 。

参数:other为用于结合的其他DataFrame

作用:将两个DataFrame 中的值合并,优先选择calling DataFrame 中的值;如果calling DataFrame 中出现空值,用other中对应的值填充。

最终合并后的对象索引为两者索引的汇总。

4.2.2 DataFrame.combine_first 实例

df1 = pd.DataFrame({'a':[1.,np.nan,5.,np.nan],
                 'b':[np.nan,2.,np.nan,6.],
                 'c':range(2,18,4)})

df2 = pd.DataFrame({'a':[5.,4.,np.nan,3.,7.],
                'b':[np.nan,3.,4.,6.,8.]})

df1.combine_first(df2)

df1                                            df2                      df1.combine_first(df2)

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第49张图片         Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第50张图片         Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第51张图片

要特别说明的是,两个DataFrame之间的作用是按照Series-wise展开的,分别按照对应的列key值,两两进行series.combine_first操作。

如上述df1和df2在用combine_first操作时,分别按照‘a’对应的两个series来进行结合,填充空值;

在按照‘b’对应的两个series来进行结合,填充空值;最后是‘c’对应的series。

举例:‘a’对应的两个series的结合

df1['a']                                                   df2['a']                                                              

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第52张图片         Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第53张图片

  df1['a'] 和 df2['a'] 作用,产生合并后新的DataFrame的第一列。

Python/Pandas 数据规整/合并数据集Merge/Concat/Join/Combine_first函数_第54张图片       

5 小结

pd.merge() 只能作用于两个对象之间,连接方式“inner”,“outer”,“left”,“right”其中之一。默认为“inner”。无轴向axis参数。

pd.concat()可以用于多个对象连接,连接方式为“inner”,“outer”其中之一,默认为“outer”。有轴向axis参数。

 .join()可以用于多个对象连接, 连接方式为‘left’, ‘right’, ‘outer’, ‘inner’其中之一,默认为“left”。无轴向axis参数。

.combine_first() 对于有索引全部相同或者部分相同的两个数据集,实现两者数据的结合。

 

(不当之处,欢迎留言,互通有无~)

 

 

你可能感兴趣的:(Python,Python,Pandas,数据分析)