4-Pandas数据预处理之数据融合(pd.merge()、df.join()、df.combine_first()详解)
一、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 江苏