首页 > 技术文章 > 4-Pandas数据预处理之数据融合(pd.merge()、df.join()、df.combine_first()详解)

Cheryol 2020-07-29 16:31 原文

一、pd.merge()

pd.merge()的常用参数
参数 说明
left 参与合并的左侧DataFrame
right 参与合并的右侧DataFrame
how

如何合并。值为{'left','right','outer','inner'},默认为'inner'

left: 仅保留左侧DataFrame中存在的键

right:仅保留右侧DataFrame中存在的键

outer:保留左右DataFrame键的交集

inner:保留左右DataFrame键的并集

on 用于连接的列名,默认是两个DataFrame重叠的列
left_on 左侧DataFrame中用作连接键的列
right_on 右侧DataFrame中用作连接键的列
left_index {True,False},将左侧的行索引用作其连接键
right_index {True,False},将右侧的行做引用作其连接键
suffixes 字符串值元组,用于追加到重叠列名的后缀,默认为('_x','_y')

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(1)先创建两个DataFrame

>>> left = pd.DataFrame({'姓名':['张某','李某','段某'],'年龄':[22,26,24]})
>>> left
   姓名  年龄
0  张某  22
1  李某  26
2  段某  24

>>> right = pd.DataFrame({'姓名':['张某','李某','钱某'],'籍贯':['北京','河北','江苏']})
>>> right
   姓名  籍贯
0  张某  北京
1  李某  河北
2  钱某  江苏

(2)在默认情况下,将重叠列当做键,也可通过参数on指定;

>>> pd.merge(left,right)
   姓名  年龄  籍贯
0  张某  22  北京
1  李某  26  河北

#通过参数on指定
>>> pd.merge(left,right,on='姓名')
   姓名  年龄  籍贯
0  张某  22  北京
1  李某  26  河北

(3)融合指标变量indicator,设置indicator的值为True,则融合结果中将增加列名为"_merge"的一列,其值代表不同含义:

取值 说明
left_only 融合的键仅在左侧的DataFrame中存在
right_only 融合的键仅在右侧的DataFrame中存在
both 融合的键左右两侧的DataFrame中均存在

 

 

 

 

>>> pd.merge(left,right,on='姓名',how='outer',indicator=True)
   姓名    年龄   籍贯      _merge
0  张某  22.0   北京        both
1  李某  26.0   河北        both
2  段某  24.0  NaN   left_only
3  钱某   NaN   江苏  right_only

  indicator也可以接受字符串,生成的指标列的列名将由”_merge“变为该字符串:

>>> pd.merge(left,right,on='姓名',how='outer',indicator='indicator_column')
   姓名    年龄   籍贯 indicator_column
0  张某  22.0   北京             both
1  李某  26.0   河北             both
2  段某  24.0  NaN        left_only
3  钱某   NaN   江苏       right_only

(4)索引与列进行融合

注:left的索引和right中的某一列均为“姓名”,现在需要根据姓名进行融合

>>> left = pd.DataFrame({'年龄':[22,26,24]},index=['张某','李某','段某'])
>>> left
    年龄
张某  22
李某  26
段某  24
>>> left.index.name='姓名'
>>> left
    年龄
姓名
张某  22
李某  26
段某  24

>>> right = pd.DataFrame({'姓名':['张某','李某','钱某'],'籍贯':['北京','河北','江苏']})
>>> right
   姓名  籍贯
0  张某  北京
1  李某  河北
2  钱某  江苏


#其中,left的索引和right中的某一列均为“姓名”,现在需要根据姓名进行融合
>>> pd.merge(left,right,how='outer',left_index=True,right_on='姓名')
     年龄  姓名   籍贯
0  22.0  张某   北京
1  26.0  李某   河北
2  24.0  段某  NaN
2   NaN  钱某   江苏

 (5)索引与索引的融合

left和right的索引均为‘姓名’,现进行融合

>>> left = pd.DataFrame({'年龄':[22,26,24]},index=['张某','李某','段某'])
>>> left.index.name='姓名'
>>> right = pd.DataFrame({'籍贯':['北京','河北','江苏']},index=['张某','李某','钱某'])
>>> right.index.name='姓名'
>>> left
    年龄
姓名
张某  22
李某  26
段某  24
>>> right
    籍贯
姓名
张某  北京
李某  河北
钱某  江苏

#left和right的索引均为‘姓名’,现进行融合
>>> pd.merge(left,right,how='outer',left_index=True,right_index=True)
      年龄   籍贯
姓名
张某  22.0   北京
李某  26.0   河北
段某  24.0  NaN
钱某   NaN   江苏

二、join()

join()函数相对于pd.merge()而言是一种更为简便的实现方式

(1)对于索引与列的融合,需要设置on参数,来指明左键

注意:此时on的值应该是具体的列,而不是索引,索引此时的实体(即join左边的对象应该是包含“姓名”列的DataFrame)

>>> left
    年龄
姓名
张某  22
李某  26
段某  24
>>> right
   姓名  籍贯
0  张某  北京
1  李某  河北
2  钱某  江苏

#注意:此时on的值应该是具体的列,而不是索引,索引此时的实体(即join左边的对象应该是包含“姓名”列的DataFrame)
>>> right.join(left,on='姓名')
   姓名  籍贯    年龄
0  张某  北京  22.0
1  李某  河北  26.0
2  钱某  江苏   NaN

 

(2)索引与索引的融合

相当于>>>pd.merge(left,right,how='outer',left_index=True,right_on='姓名')

>>> left
    年龄
姓名
张某  22
李某  26
段某  24
>>> right
    籍贯
姓名
张某  北京
李某  河北
钱某  江苏

>>> left.join(right,how='outer')
      年龄   籍贯
姓名
张某  22.0   北京
李某  26.0   河北
段某  24.0  NaN
钱某   NaN   江苏

注意:merge和joiny都有参数sort,当sort=True时表示连接后的结果会按照连接变量进行升序排列。

例:>>>pd.merge(test_user,test_loan,how='outer',left_on='user_id',right_on='user',sort=True)

三、combine_first()

  由于数据融合是有一种常见的现象,即:需要根据一个DataFrame对象中的值为另一个DataFrame中的值做缺失值处理;

于是combine_first()应运而生,该方法实现了用参数对象中的数据为调用者对象的缺失数据“打补丁”,且会自动对其索引。

>>> left = pd.DataFrame({'姓名':['张某','李某','段某'],'年龄':[22,26,24]})
>>> right = pd.DataFrame({'姓名':['张某','李某','段某'],'年龄':[22,np.nan,np.nan],'籍贯':['北京','河北','江苏']})

#根据left中的值去填补right中的值
>>> right.combine_first(left)
   姓名    年龄  籍贯
0  张某  22.0  北京
1  李某  26.0  河北
2  段某  24.0  江苏

 

  

 

推荐阅读