【Python】数据分析常用函数merge

114 阅读6分钟

merge函数位于pandas库中,用于合并连接DateFrame或者Series,其中Series对象可视为DataFrame的一个单列。

pd.merge(
    df1,
    df2,
    how='inner',
    on=None,
    left_on=None,
    right_on=None,
    left_index=None,
    right_index=None,
    sort=None,
    suffixes=('_x','_y'),
    copy=None,
    indicator=None,
    validate=None
)

参数如下:

  • df1:DataFrame或者已命名的Series

    拼接的DataFrame1,哪个表在前则为左表

  • df2:DataFrame或者已命名的Series

    拼接的DataFrame2,哪个表在后则为右表

  • how:{'left', 'right', 'outer', 'inner', 'cross'},默认为 'inner'

    left:仅使用左DataFrame的字典,类似于SQL的左连接,保留字典的排序

    right:仅使用右DataFrame的字典,类似于SQL的右连接,保留字典的排序

    outer:使用两DataFrame字典的并集,类似于SQL的外连接,按照字典顺序排序

    inner:使用两DataFrame字典的交集,类似于SQL的内连接,保留左DataFrame字典顺序

    cross:创建两DataFrame的笛卡尔乘积,保留左DataFrame字典顺序

  • on:标签或列表

    需要连接的列,必须在左DataFrame和右DataFrame中同时存在。如果on值为None且left_index和right_index为False,默认名字相同的字段连接。

  • left_on:标签或列表

    左DataFrame需要连接的列或索引级别键(列标签)

  • right_on:标签或列表

    右DataFrame需要连接的列或索引级别键(列标签)

  • left_index:bool,默认为False

    如果为True,则使用左表中的行标签作为其连接键。 对于多级索引的表,级别数必须与右表 的连接键数相匹配。

  • right_index:bool,默认为False

    与left_index类似

  • sort:布尔值,默认为False

    对输出DataFrame的字典进行排序。如果为False,则根据其连接方式进行排序。

  • suffixes:

    用于重叠列的字符串后缀元组。 默认为('_x','_y')

  • copy:bool,默认为False

    复制传递对象

  • indicator:bool或str,默认为False

    如果为True,添加一列名为"_merge"到输出的DataFrame,其中包含各行的数据来源。“_merge”包括三种分类:left_only、right_only、both,其中left_only指合并键仅出现在左DataFrame,right_only指合并键仅出现在右DataFrame,both指合并键在左右DataFrame都有。如果indicator输入的是str,该列被命名对应的str值。

  • validate:str,可选择的,默认为None,检查merge是否为特定类型

    “one_to_one”或“1:1”:检查合并键在左DataFrame和右DataFrame内是否唯一

    “one_to_many”或“1:m”:检查合并键在左DataFrame内是否唯一

    “many_to_one”或“m:1”:检查合并键在右DataFrame内是否唯一

    “many_to_many”或“m:m”:但不会引发检查

实例:

1、创建DataFrame,或者导入数据表。

import pandas as pd
df1 = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六','boss'],
    '职位': ['总经理', '组长', '业务员', '实习生','老板'],
    '工资': ['10000', '7000', '5000', '3000','30000']
    })
df2 = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六','孙七'],
    '职位': ['总经理', '组长', '业务员', '实习生','兼职'],
    '上班天数': [22,22,26,22,15],
    '绩效':[10000,8000,6000,0,0]
    })

2、左连接

pd.merge(df1,df2,how='left',on=['姓名','职位'])

image.png

3、右连接

pd.merge(df1,df2,how='right',on=['姓名','职位'])

4、内连接(此时的内连接与左连接一样)

pd.merge(df1,df2,how='inner',on=['姓名','职位'])

image.png

5、外连接

pd.merge(df1,df2,how='outer',on=['姓名','职位'])

image.png

6、left_on, right_on

当两个表的字段名不完全一致时,就需要用left_on和right_on。请看以下例子:

df1 = pd.DataFrame({
    '员工姓名': ['张三', '李四', '王五', '赵六','boss'],
    '员工职位': ['总经理', '组长', '业务员', '实习生','老板'],
    '工资': ['10000', '7000', '5000', '3000','30000']
    })
df2 = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六','孙七'],
    '职位': ['总经理', '组长', '业务员', '实习生','兼职'],
    '上班天数': [22,22,26,22,15],
    '绩效':[10000,8000,6000,0,0]
    })

此时df1的字段名为员工姓名、员工职位、工资,df2的字段名为姓名、职位、上班天数、绩效,显然员工姓名和姓名实际上是同一个字段,员工职位和职位也是同一个字段,所以

pd.merge(df1, df2, left_on=['员工姓名', '员工职位'], right_on=['姓名', '职位'], how='left')

image.png

7、left_index、right_index

left_index、right_index的用法与left_on、right_on类似,它们的区别在于一个根据index匹配,一个根据column匹配。left_index、right_index需要一起使用且同时为True。

pd.merge(df1, df2, left_index=True, right_index=True, how='left')

image.png

事实上left_index、right_index与left_on、right_on可以混用,前提是对应的index和column的名字相同。

df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3'],
                   'key': ['X', 'X', 'Y', 'Y']})
df2 = pd.DataFrame({'C': ['C0', 'C1'],
                      'D': ['D0', 'D1']},
                    index=['X', 'Y'])
pd.merge(df1, df2, right_index=True, left_on='key', how='right')

8、sort

sort对连接的键值进行排序,sort为True时进行排序,False时保留原来的排序。

import pandas as pd
df1 = pd.DataFrame({
    '员工姓名': ['张三', '李四', '王五', '赵六','boss'],
    '员工职位': ['总经理', '组长', '业务员', '实习生','老板'],
    '工资': ['10000', '7000', '5000', '3000','30000']
    })
df2 = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六','孙七'],
    '职位': ['总经理', '组长', '业务员', '实习生','兼职'],
    '上班天数': [22,22,26,22,15],
    '绩效':[10000,8000,6000,0,0]
    })
 
pd.merge(df1, df2, left_on='员工姓名', right_on='姓名',  how='right', sort=True)

image.png

9、suffixes

当两表有名字相同的字段时,pandas自动给它们添加后缀,默认左表的字段名后面添加'_x',右表的字段名后面添加'_y'。设置suffixes的值则修改后缀。

import pandas as pd
df1 = pd.DataFrame({
    '员工姓名': ['张三', '李四', '王五', '赵六','boss'],
    '职位': ['总经理', '组长', '业务员', '实习生','老板'],
    '工资': ['10000', '7000', '5000', '3000','30000']
    })
df2 = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六','孙七'],
    '职位': ['总经理', '组长', '业务员', '实习生','兼职'],
    '上班天数': [22,22,26,22,15],
    '绩效':[10000,8000,6000,0,0]
    })
 
pd.merge(df1, df2, left_on='员工姓名', right_on='姓名',  how='right', suffixes=('1', '2'))

image.png

10、indicator

indicator返回匹配的结果来源,indicator可以输入布尔值和字符串参数。indicator返回结果有以下三种情况:

匹配情况返回值
只有左表left_only
只有右表right_only
两表都有both
import pandas as pd
df1 = pd.DataFrame({
    '员工姓名': ['张三', '李四', '王五', '赵六','boss'],
    '职位': ['总经理', '组长', '业务员', '实习生','老板'],
    '工资': ['10000', '7000', '5000', '3000','30000']
    })
df2 = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六','孙七'],
    '职位': ['总经理', '组长', '业务员', '实习生','兼职'],
    '上班天数': [22,22,26,22,15],
    '绩效':[10000,8000,6000,0,0]
    })
 
pd.merge(df1, df2, left_on='员工姓名', right_on='姓名',  how='right', indicator=True)

image.png

显然孙七只有右表才有,其他人两表都有。

将indicator设置为字符串,即将默认列名'_merge'修改成设置的名字。

pd.merge(df1, df2, left_on='员工姓名', right_on='姓名',  how='right', indicator='merge_result')

image.png