• pandas之DataFrame合并merge


    一、merge

    merge操作实现两个DataFrame之间的合并,类似于sql两个表之间的关联查询。merge的使用方法及参数解释如下:

    pd.merge(left, right, on=None, how='inner', left_on=None, right_on=None, left_index=False, right_index=False, 
       sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
    • left和right:第一个DataFrame和第二个DataFrame对象,merge只能实现两个DataFrame的合并,无法一次实现多个合并
    • on:指定参考column,要求两个df必须至少有一个相同的column,默认为None以最多相同的column为参考
    • how:合并的方式,默认为inner取参考column的交集,outer取并集保留所有行;outer、left、right中的缺失值都以NaN填充;left按照左边对象为参考进行合并即保留左边的所有行,right按照右边对象为参考进行合并即保留右边所有行,
    • left_on=None和right_on=None:以上on是在两个df有相同的column的情况下使用,如果两个df没有相同的column,使用left_on和right_on分别指明左边和右边的参考column
    • left_index和right_index:指定是否以索引为参考进行合并
    • sort:合并结果是否按on指定的参考进行排序
    • suffixed:合并后如果有重复column,分别加上什么后缀 

    下面对每个参数进行演示

    on:指定参考column,如果不指定默认为None,以两者相同列的最多数为参考;index重新生成为从0开始的整数。

    df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n',])
    df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H'],'key4':['i','j','K','L']},index = ['p','q','u','v'])
    print(df1)
    print(df2)
    print(pd.merge(df1,df2,on='key1'))
    print(pd.merge(df1,df2,on='key2'))
    print(pd.merge(df1,df2,on=['key1','key2']))
    print(pd.merge(df1,df2))  #可以看到不加on参数,系统自动以个数最多的相同column为参考
    #   key1 key2 key3
    # k    a    e    i
    # l    b    f    j
    # m    c    g    k
    # n    d    h    l
    #   key1 key2 key4
    # p    a    e    i
    # q    B    f    j
    # u    c    g    K
    # v    d    H    L
    #   key1 key2_x key3 key2_y key4
    # 0    a      e    i      e    i
    # 1    c      g    k      g    K
    # 2    d      h    l      H    L
    #   key1_x key2 key3 key1_y key4
    # 0      a    e    i      a    i
    # 1      b    f    j      B    j
    # 2      c    g    k      c    K
    #   key1 key2 key3 key4
    # 0    a    e    i    i
    # 1    c    g    k    K
    #   key1 key2 key3 key4
    # 0    a    e    i    i
    # 1    c    g    k    K
    参数on演示

    how:指定合并方式,如果不指定默认为inner

    inner相当于sql中的=,outer相当于sql中的full join,left相当于sql中的left join,right相当于sql中的right join;index重新生成为从0开始的整数。

    对于outer、left、right来说可能会出现缺失值,全部以NaN填充。

    df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n',])
    df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H'],'key4':['i','j','K','L']},index = ['p','q','u','v'])
    print(df1)
    print(df2)
    print(pd.merge(df1,df2,how='inner'))   #默认方式,取交集
    print(pd.merge(df1,df2,how='outer'))   #取并集
    print(pd.merge(df1,df2,how='left'))    #以左边为参考,即保留左边所有行
    print(pd.merge(df1,df2,how='right'))   #以右边为参考,即保留右边所有行
    #   key1 key2 key3
    # k    a    e    i
    # l    b    f    j
    # m    c    g    k
    # n    d    h    l
    #   key1 key2 key4
    # p    a    e    i
    # q    B    f    j
    # u    c    g    K
    # v    d    H    L
    #   key1 key2 key3 key4
    # 0    a    e    i    i
    # 1    c    g    k    K
    #   key1 key2 key3 key4
    # 0    a    e    i    i
    # 1    b    f    j  NaN
    # 2    c    g    k    K
    # 3    d    h    l  NaN
    # 4    B    f  NaN    j
    # 5    d    H  NaN    L
    #   key1 key2 key3 key4
    # 0    a    e    i    i
    # 1    b    f    j  NaN
    # 2    c    g    k    K
    # 3    d    h    l  NaN
    #   key1 key2 key3 key4
    # 0    a    e    i    i
    # 1    c    g    k    K
    # 2    B    f  NaN    j
    # 3    d    H  NaN    L
    参数how演示

    left_on和right_on:默认都为False,但是如果两个DataFrame没有相同的column而又需要对它们的按列合并,则需要使用left_on和right_on分别指明两边的参考列;index重新生成为从0开始的整数。

    但是left_on和right_on不是必须成对出现,下面关于left_index和right_index会涉及到。

    df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n'])
    df2 = pd.DataFrame({'key4':['a','B','c','d'],'key5':['e','f','g','H'],'key6':['i','j','K','L']},index = ['p','q','u','v'])
    print(df1)
    print(df2)
    # print(pd.merge(df1,df2,df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n'])
    df2 = pd.DataFrame({'key4':['a','B','c','d'],'key5':['e','f','g','H'],'key6':['i','j','K','L']},index = ['p','q','u','v'])
    print(df1)
    print(df2)
    # print(pd.merge(df1,df2,left_on='key1',right_on='key4'))
    #   key1 key2 key3
    # k    a    e    i
    # l    b    f    j
    # m    c    g    k
    # n    d    h    l
    #   key4 key5 key6
    # p    a    e    i
    # q    B    f    j
    # u    c    g    K
    # v    d    H    L
    #   key1 key2 key3 key4 key5 key6
    # 0    a    e    i    a    e    i
    # 1    c    g    k    c    g    K
    # 2    d    h    l    d    H    L='key1',right_on='key4'))
    #   key1 key2 key3
    # k    a    e    i
    # l    b    f    j
    # m    c    g    k
    # n    d    h    l
    #   key4 key5 key6
    # p    a    e    i
    # q    B    f    j
    # u    c    g    K
    # v    d    H    L
    #   key1 key2 key3 key4 key5 key6
    # 0    a    e    i    a    e    i
    # 1    c    g    k    c    g    K
    # 2    d    h    l    d    H    L
    参数left_on和right_on演示

    left_index和right_index:默认都为False,如果需要按索引进行合并,则需要使用left_index和right_index指明以index为参考。(on、left_on、right_on都是指定以column为参考)

    如果使用了left_index或者right_index,必须指明另一方的参考键。

    结果除了包含两个DataFrame的所有列,还会生成一个新的列,新列即以指定的两个参考进行合并后的结果。

    如果是left_on =  '**' 和right_index = True或者left_index =  True 和right_on = '**',index取on所在的一方,如果是left_index =  True和right_index = True,取两者相同的即可。

    df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h']},index=['k','l','m','n'])
    df2 = pd.DataFrame({'key1':['k',6,'l']},index=['a','m','c'])
    print(df1)
    print(df2)
    print(pd.merge(df1,df2,left_on='key1',right_index=True))  #index取df1的
    print(pd.merge(df1,df2,left_index=True,right_on='key1'))   #index取df2的
    print(pd.merge(df1,df2,left_index=True,right_index=True))  #index取两者交集
    #   key1 key2
    # k    a    e
    # l    b    f
    # m    c    g
    # n    d    h
    #   key1
    # a    k
    # m    6
    # c    l
    #   key1 key1_x key2 key1_y
    # k    a      a    e      k
    # m    c      c    g      l
    #   key1 key1_x key2 key1_y
    # a    k      a    e      k
    # c    l      b    f      l
    #   key1_x key2 key1_y
    # m      c    g      6
    参数left_index和right_index演示

    sort:结果是否按照参考进行排序,默认不排序;数字按照大小排序,字符串按照A-Za-z排序。

    merge结果的显示顺序默认是按照df1、df2的行顺序进行显示,

    df1 = pd.DataFrame({'key1':['d','a','c','B'],'key2':[3,6,1,8]},index=['k','l','m','n'])
    df2 = pd.DataFrame({'key1':['c','B','a','d'],'key2':[3,8,2,1]},index = ['p','q','u','v'])
    print(df1)
    print(df2)
    print(pd.merge(df1,df2,on='key2',))
    print(pd.merge(df1,df2,on='key1',sort=True))
    #   key1  key2
    # k    d     3
    # l    a     6
    # m    c     1
    # n    B     8
    #   key1  key2
    # p    c     3
    # q    B     8
    # u    a     2
    # v    d     1
    #   key1_x  key2 key1_y
    # 0      d     3      c
    # 1      c     1      d
    # 2      B     8      B
    #   key1  key2_x  key2_y
    # 0    B       8       8
    # 1    a       6       2
    # 2    c       1       3
    # 3    d       3       1
    参数sort演示

    pandas自带的排序方法df.sort_index()、df.sort_values('column')

    suffixes:如果两者相同的column未被指定为参考列,那么结果中这两个相同的column名称会被加上后缀,默认为左右分别为_x和_y

    df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h']},index=['k','l','m','n',])
    df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H']},index = ['p','q','u','v'])
    print(df1)
    print(df2)
    print(pd.merge(df1,df2,on='key1'))
    print(pd.merge(df1,df2,on='key2',suffixes=('_df1','_df2')))
    #   key1 key2_x key2_y
    # 0    a      e      e
    # 1    c      g      g
    # 2    d      h      H
    #   key1_df1 key2 key1_df2
    # 0        a    e        a
    # 1        b    f        B
    # 2        c    g        c
    参数suffixed演示

    二、join

    join是默认按照index、以left方式实现两个DataFrame的合并,即默认用法相当于merge的pd.merge(df1,df2,how = 'left',left_index =  True,right_index = True),缺失值默认为NaN

    df1.join(df2, on=None, how='left', lsuffix='', rsuffix='',sort=False)

    由于join的lsuffix和rsuffix默认值为空,因此如果两者有相同的column,一定要手动指定这两个参数,否则会报错。

    join也可以通过on指定前面的DataFrame以column为参考与后面的index关联实现合并,即相当于merge的pd.merge(df1,df2,how = 'left',left_on ='**',right_index = True)。

    index重新生成为从0开始的整数。

    df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':[1,2,3,4]})
    df2 = pd.DataFrame({'key1':['a','B','c','d'],'key3':['e','f','g','H']})
    print(df1)
    print(df2)
    print(df1.join(df2,on='key2',lsuffix='_df1',rsuffix='_df2'))
    #   key1  key2
    # 0    a     1
    # 1    b     2
    # 2    c     3
    # 3    d     4
    #   key1 key3
    # 0    a    e
    # 1    B    f
    # 2    c    g
    # 3    d    H
    #   key1_df1  key2 key1_df2 key3
    # 0        a     1        B    f
    # 1        b     2        c    g
    # 2        c     3        d    H
    # 3        d     4      NaN  NaN
    join演示

    三、concat

    上述merge和join都是指定了column或者index为参考对两个DataFrame进行合并,concat是单纯的对DataFrame进行堆叠,并且空值填充为NaN。

    concat可一次实现对多个pandas对象的堆叠,默认是对所有列在垂直方向进行堆叠、index为原来各自的索引。

    concat( [obj1, obj2, obj3], axis=0, join="outer", join_axes=None, ignore_index=False, keys=None, 
         levels=None, names=None, verify_integrity=False, sort=None, copy=True)

    如果是在水平方向进行堆叠,需要指定axis=1,如果合并后有相同列名称,可通过add_prefix或者add_suffix为其中一个添加名称后缀。

    s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
    s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
    print(s1)
    print(s2)
    print(pd.concat([s1,s2]))
    print(pd.concat([s1,s2],axis=1,sort=False))
    # a    1
    # b    2
    # c    3
    # Name: s1, dtype: int64
    # c    3
    # x    4
    # y    w
    # Name: s2, dtype: object
    # a    1
    # b    2
    # c    3
    # c    3
    # x    4
    # y    w
    # dtype: object
    #     s1   s2
    # a  1.0  NaN
    # b  2.0  NaN
    # c  3.0    3
    # x  NaN    4
    # y  NaN    w
    参数axis演示

    join表示堆叠方式,默认为outer,只有outer和inner方式,inner表示只对相同列进行堆叠。

    s1 = pd.DataFrame([[1,2,3],[4,5,6]],columns=['a','b','c'])
    s2 = pd.DataFrame([[3,4,'w'],[5,6,'x']],columns=['a','b','d'])
    print(s1)
    print(s2)
    print(pd.concat([s1,s2]))
    print(pd.concat([s1,s2],join="inner"))
    #    a  b  c
    # 0  1  2  3
    # 1  4  5  6
    #    a  b  d
    # 0  3  4  w
    # 1  5  6  x
    #    a  b    c    d
    # 0  1  2  3.0  NaN
    # 1  4  5  6.0  NaN
    # 0  3  4  NaN    w
    # 1  5  6  NaN    x
    #    a  b
    # 0  1  2
    # 1  4  5
    # 0  3  4
    # 1  5  6
    参数join演示

    ignore_index表示是否保留原对象的index,默认保留,True表示结果的index为从0开始的整数。

    s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
    s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
    print(pd.concat([s1,s2]))
    print(pd.concat([s1,s2],ignore_index=True))
    # a    1
    # b    2
    # c    3
    # c    3
    # x    4
    # y    w
    # dtype: object
    # 0    1
    # 1    2
    # 2    3
    # 3    3
    # 4    4
    # 5    w
    # dtype: object
    参数ignore_index演示

    join_axes指定结果显示的行索引

    s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
    s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
    print(pd.concat([s1,s2],axis=1))
    print(pd.concat([s1,s2],axis=1,join_axes=[['a','c']]))
    #     s1   s2
    # a  1.0  NaN
    # b  2.0  NaN
    # c  3.0    3
    # x  NaN    4
    # y  NaN    w
    #    s1   s2
    # a   1  NaN
    # c   3    3
    参数join_axes演示

    对于Seris来说,默认按照竖直方向堆叠,如果再指定keys,则会形成一个层次索引。

    如果在设置axis=1的情况下即按照水平方向进行堆叠,再指定keys,则keys的值会成为column。

    s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
    s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
    print(pd.concat([s1,s2]))   #竖直方向堆叠
    print(pd.concat([s1,s2],keys=['s1','s2']))   #竖直方向堆叠,并形成一个层次索引
    print(pd.concat([s1,s2],axis=1,keys=['s1','s2']))   #水平方向堆叠,keys的值为column
    # a    1
    # b    2
    # c    3
    # c    3
    # x    4
    # y    w
    # dtype: object
    # s1  a    1
    #     b    2
    #     c    3
    # s2  c    3
    #     x    4
    #     y    w
    # dtype: object
    #     s1   s2
    # a  1.0  NaN
    # b  2.0  NaN
    # c  3.0    3
    # x  NaN    4
    # y  NaN    w
    参数keys演示

    四、替换空值combine_first

    在相同index和column的位置,用一个对象的值去替换另一个对象的空值NaN。

    df1.combine_forst(df2),如果df2有不在df1中的index和column,直接追加上去。

    df1 = pd.DataFrame([[1,np.nan,3],[np.nan,5,6]],columns=['a','b','c'])
    df2 = pd.DataFrame([[3,4,'w'],[5,6,'x'],[7,8,9]],columns=['a','b','d'])
    print(df1)
    print(df2)
    print(df1.combine_first(df2))  #对于index为0和1,在对应column位置使用df2的值替换df1的空值
    #df2中的index=2和column='d'不在df1中,结果保留这一行和这里一列,
    #      a    b  c
    # 0  1.0  NaN  3
    # 1  NaN  5.0  6
    #    a  b  d
    # 0  3  4  w
    # 1  5  6  x
    # 2  7  8  9
    #      a    b    c  d
    # 0  1.0  4.0  3.0  w
    # 1  5.0  5.0  6.0  x
    # 2  7.0  8.0  NaN  9
    combine_first演示

    五、更新update

    在相同index和column的位置,使用一个对象的值去更新原对象的值,该方法没有返回值,直接修改原对象。

    df1.update(df2),更新df1,结果只包含原对象的行和列。

    df1 = pd.DataFrame([[1,np.nan,3],[np.nan,5,6]],columns=['a','b','c'])
    df2 = pd.DataFrame([[3,4,'w'],[5,6,'x'],[7,8,9]],columns=['a','b','d'])
    df1.update(df2)  #没有返回值,直接打印结果为none,且df2中的第3行和d列不追加到df1
    print(df1)   
    #      a    b  c
    # 0  3.0  4.0  3
    # 1  5.0  6.0  6
    update演示

    六、去重duplicate与drop_duplicates

    duplicate()结果是一个值为布尔的Seris,通过obj[ df.duplicated()==False ]来取出Seris和DataFrame中的重复值、行,新结果的index为False对应的索引。

    对于Seris,从第一个值开始判断,如果元素第一次出现,则duplicate后的值为True,否则为False

    对应于DataFrame,从第一行开始判断,如果行的内容第一次出现(要求行内元素顺序一致),则duplicate后的值为True,否则为False。如

    s = pd.Series([1,2,2,1,3,3])
    print(s.duplicated())
    print(s[s.duplicated()==False])
    print('----------------')
    df = pd.DataFrame([[1,2,3],[4,5,6],[1,3,2],[4,5,6],[7,8,9]])
    print(df.duplicated())   #[1,2,3]和[1,3,2]不重复
    print(df[df.duplicated()==False])
    # 0    False
    # 1    False
    # 2     True
    # 3     True
    # 4    False
    # 5     True
    # dtype: bool
    # 0    1
    # 1    2
    # 4    3
    # dtype: int64
    # ----------------
    # 0    False
    # 1    False
    # 2    False
    # 3     True
    # 4    False
    # dtype: bool
    #    0  1  2
    # 0  1  2  3
    # 1  4  5  6
    # 2  1  3  2
    # 4  7  8  9
    duplicated去重

    drop_duplicates( )删除重复的元素,默认生成新的结果不修改原对象,如果添加参数inplace=True则直接修改原对象。新结果的index为元素第一次出现时对应的索引

    s = pd.Series([1,2,2,1,3,3])
    print(s.drop_duplicates())
    df = pd.DataFrame([[1,2,3],[4,5,6],[1,3,2],[4,5,6],[7,8,9]])
    df.drop_duplicates(inplace=True)
    print(df)
    # 0    1
    # 1    2
    # 4    3
    # dtype: int64
    #    0  1  2
    # 0  1  2  3
    # 1  4  5  6
    # 2  1  3  2
    # 4  7  8  9
    drop_duplicates去重

    七、替换replace

    replace('原元素','新元素')将原元素替换成新元素

    如果要同时替换多个元素,用列表表示即可;如果要将不同的元素替换成不同的内容,使用字典。

    s = pd.Series(list('abcafc'))
    print(s.replace('a','A'))  #将每个a替换成A
    print(s.replace(['a','b'],'W'))   #将所有a、b替换成W
    print(s.replace({'a':'A','f':'F'}))   #将a替换成A,f替换成F
    
    df = pd.DataFrame([[1,2,3],[4,5,6],[2,5,8]])
    print(df.replace(2,'a'))   #将2替换成a
    replace演示
  • 相关阅读:
    攻城狮在路上(肆)How tomcat works(一) 简单的web服务器
    攻城狮在路上(肆)How tomcat works(零) 前言说明
    font-face使用备忘
    subversion安装使用
    判断一个类到底是从哪个jar包中调用的工具类
    JavaScript实例
    Nginx(一)
    PHP面向对象(七)
    PHP面向对象(六)
    PHP面向对象(五)
  • 原文地址:https://www.cnblogs.com/Forever77/p/11285302.html
Copyright © 2020-2023  润新知