zoukankan      html  css  js  c++  java
  • Python学习笔记:数据合并join、merge、concat、append、combine、combine_first等

    一、对比总结

    简单总结,通过 mergejoin 合并的数据后数据的列变多,通过 concat 合并后的数据行列都可以变多(axis=1),而 combine_first 可以用一个数据填充另一个数据的缺失数据。

    函数 说明
    join 主要用于基于索引的横向合并拼接
    merge 主要用于基于指定列的横向合并拼接(类似SQL的inner join等)
    concat 可用于横向和纵向合并拼接
    append 主要用于纵向追加
    combine 将2个DataFrame按列进行组合
    combine_first 为数据打补丁

    二、join

    join 是基于索引的横向拼接,如果索引一致,直接横向拼接。

    如果索引不一致,则会用 Nan 值填充。

    # 索引一致
    import pandas as pd
    x = pd.DataFrame({'A':['x1','x2','x3'],
                      'B':['y1','y2','y3']}, index=[0,1,2])
    y = pd.DataFrame({'C':['z1','z2','z3'],
                      'D':['m1','m2','m3']}, index=[0,1,2])
    x.join(y)
    '''
    	A	B	C	D
    0	x1	y1	z1	m1
    1	x2	y2	z2	m2
    2	x3	y3	z3	m3
    '''
    
    # 索引不一致
    import pandas as pd
    x = pd.DataFrame({'A':['x1','x2','x3'],
                      'B':['y1','y2','y3']}, index=[0,1,2])
    y = pd.DataFrame({'C':['z1','z2','z3'],
                      'D':['m1','m2','m3']}, index=[1,2,3])
    x.join(y)
    '''
    	A	B	C	D
    0	x1	y1	NaN	NaN
    1	x2	y2	z1	m1
    2	x3	y3	z2	m2
    '''
    
    # 合并的列名相同 指定 lsuffix、rsuffix 进行区分
    import pandas as pd
    x = pd.DataFrame({'A':['x1','x2','x3'],
                      'B':['y1','y2','y3']}, index=[0,1,2])
    y = pd.DataFrame({'B':['z1','z2','z3'],
                      'D':['m1','m2','m3']}, index=[0,1,2])
    x.join(y, lsuffix='_xx', rsuffix='_yy')
    '''
        A B_xx B_yy   D
    0  x1   y1   z1  m1
    1  x2   y2   z2  m2
    2  x3   y3   z3  m3
    '''
    

    三、merge

    merge 是基于指定列的横向拼接,类似于数据库的 left joinright joininner join 等连接方式,可以根据一个或多个键将不同的 DataFrame 连接起来。

    该函数的典型应用场景是,针对同一个主键存在两张不同字段的表,根据主键整合到一张表里面。

    可以指定不同的how参数,表示连接方式。

    • inner 内连
    • left 左连
    • right 右连
    • outer 全连,默认为 inner

    需要注意的是使用 merge 合并时,两个数据集的合并条件类型须一致。

    1.使用语法

    pd.merge(left_data, right_data, how='inner', on=None, left_on=None, right_on=None, 
            left_index=False, right_index=False, sort=False, suffixes=('-x', '-y'), 
            copy=True, indicator=False, validate=None)
    

    2.参数

    • left: 拼接的左侧DataFrame对象
    • right: 拼接的右侧DataFrame对象
    • on: 要加入的列或索引级别名称。 必须在左侧和右侧DataFrame对象中找到。 如果未传递且left_index和right_index为False,则DataFrame中的列的交集将被推断为连接键。
    • left_on:左侧DataFrame中的列或索引级别用作键。 可以是列名,索引级名称,也可以是长度等于DataFrame长度的数组。
    • right_on: 左侧DataFrame中的列或索引级别用作键。 可以是列名,索引级名称,也可以是长度等于DataFrame长度的数组。
    • left_index: 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。 对于具有MultiIndex(分层)的DataFrame,级别数必须与右侧DataFrame中的连接键数相匹配。
    • right_index: 与left_index功能相似。
    • how::取值为‘left’, ‘right’, ‘outer’, ‘inner’。 默认inner。inner是取交集,outer取并集,没出现的会将缺失的部分添加缺失值。
    • sort: 按字典顺序通过连接键对结果DataFrame进行排序。 默认为False,设置为False将在很多情况下显着提高性能。
    • suffixes: 用于重叠列的字符串后缀元组。 默认为(‘_x’,’ _y’)。
    • copy:始终从传递的DataFrame对象复制数据(默认为True),即使不需要重建索引也是如此。
    • indicator:将一列添加到名为_merge的输出DataFrame,其中包含有关每行源的信息。 _merge 是分类类型,并且对于其合并键仅出现在“左”DataFrame中的观察值,取得值为left_only,对于其合并键仅出现在“右”DataFrame中的观察值为right_only,并且如果在两者中都找到观察点的合并键,则为both。

    3.实操

    • 左右连接键名一致
    # 创建测试表
    import pandas as pd
    df1=pd.DataFrame({'key':['a','b','a','b','b'],'value1':range(5)})
    df2=pd.DataFrame({'key':['a','c','c','c','c'],'value2':range(5)})
    
    # 左右连接键名一致
    # 以df1、df2中相同的列名key进行连接,默认how='inner', 等同于 pd.merge(df1,df2,on='key',how='inner')
    pd.merge(df1, df2)
    '''
      key  value1  value2
    0   a       0       0
    1   a       2       0
    '''
    
    # 左连接 没有值则用NaN填充
    pd.merge(df1, df2, how='left') # 左
    pd.merge(df1, df2, how='right') # 右
    '''
    key	value1	value2
    0	a	0	0.0
    1	b	1	NaN
    2	a	2	0.0
    3	b	3	NaN
    4	b	4	NaN
    '''
    
    # 全连接 取并集 没有值则用NaN填充
    pd.merge(df1, df2, how='outer')
    '''
      key  value1  value2
    0   a     0.0     0.0
    1   a     2.0     0.0
    2   b     1.0     NaN
    3   b     3.0     NaN
    4   b     4.0     NaN
    5   c     NaN     1.0
    6   c     NaN     2.0
    7   c     NaN     3.0
    8   c     NaN     4.0
    '''
    
    • 左右连接键名不一致 可以使用left_on、right_on进行指定
    # 左右连接键名不一致 可以使用left_on、right_on进行指定
    df3=pd.DataFrame({'lkey':['a','b','a','b','b'],'data1':range(5)})
    df4=pd.DataFrame({'rkey':['a','c','c','c','c'],'data2':range(5)})
    
    # 连接
    pd.merge(df3, df4, left_on='lkey', right_on='rkey')  # 内连接 默认 how='inner'
    pd.merge(df3, df4, left_on='lkey', right_on='rkey', how='outer') # 全连接
    pd.merge(df3, df4, left_on='lkey', right_on='rkey', how='left') # 左连接
    pd.merge(df3, df4, left_on='lkey', right_on='rkey', how='right') # 右连接
    
    • 索引作为连接键
    import numpy as np
    df5=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=['v1','v2','v3','v4'])
    df6=pd.DataFrame(np.arange(12,24,1).reshape(3,4),index=list('abd'),columns=['v5','v6','v7','v8'])
    
    pd.merge(df5, df6, left_index=True, right_index=True)
    pd.merge(df5, df6, left_index=True, right_index=True, how='outer')
    
    • 传入on的参数为列表(多个连接键)
    df7 = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                          'key2': ['K0', 'K1', 'K0', 'K1'],
                             'A': ['A0', 'A1', 'A2', 'A3'],
                             'B': ['B0', 'B1', 'B2', 'B3']})
    
    df8 = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                          'key2': ['K0', 'K0', 'K0', 'K0'],
                             'C': ['C0', 'C1', 'C2', 'C3'],
                             'D': ['D0', 'D1', 'D2', 'D3']})
    # 多键连接
    pd.merge(df7, df8, on=['key1', 'key2'])
    
    • 列名相同添加后缀
    df9=pd.DataFrame({'key':['a','b','a','b','b'],'data':range(5)})
    df10=pd.DataFrame({'key':['a','c','c','c','c'],'data':range(5)})
    
    pd.merge(df9, df10, on='key')
    '''
      key  data_x  data_y
    0   a       0       0
    1   a       2       0
    '''
    
    pd.merge(df9, df10, on='key', suffixes=('_123', '_456'))
    '''
      key  data_123  data_456
    0   a         0         0
    1   a         2         0
    '''
    
    • 传入 indicator 参数
    # 添加一列 显示数据关联使用情况
    pd.merge(df1, df2, indicator=True, how='outer')
    '''
      key  value1  value2      _merge
    0   a     0.0     0.0        both
    1   a     2.0     0.0        both
    2   b     1.0     NaN   left_only
    3   b     3.0     NaN   left_only
    4   b     4.0     NaN   left_only
    5   c     NaN     1.0  right_only
    6   c     NaN     2.0  right_only
    7   c     NaN     3.0  right_only
    8   c     NaN     4.0  right_only
    '''
    
    # 指标参数也接受字符串参数 作为指标列名称
    pd.merge(df1, df2, indicator='is_used', how='outer')
    '''
      key  value1  value2     is_used
    0   a     0.0     0.0        both
    1   a     2.0     0.0        both
    2   b     1.0     NaN   left_only
    '''
    
    • sort 对连接键进行排序
    pd.merge(df3, df4, how='outer', sort=True)
    

    merge 的应用场景是针对连接键来进行操作的,连接键可以是 index 或者 column

    但是实际应用时一定注意的是 left 或者 right 的键值不要重复,避免麻烦。

    • 多数据框合并
    # 一个一个拼接
    pf.merge(pd.merge(df1, df2, how='left'), df3, how='left')
    

    四、concat

    concat 函数既可以用于横向拼接,也可以用于纵向拼接。

    # 默认纵向拼接
    # 列名相同直接拼接 列名不同 不存在的值为NaN
    import pandas as pd
    df1=pd.DataFrame({'key':['a','b','a','b','b'],'value1':range(5)})
    df2=pd.DataFrame({'key':['a','c','c','c','c'],'value2':range(5)})
    pd.concat([df1, df2], axis=1) # 横向
    pd.concat([df1, df2], axis=0) # 纵向
    
    # ignore_index 忽略原来的索引 自动生成新索引
    pd.concat([df1, df2], axis=0, ignore_index=True)
    
    # 多数据集合并
    pd.concat([df1, df2, df3, ...])
    
    # 利用keys生成多重索引 判断数据来源
    pd.concat([df1, df2, df3], keys=[1,2,3])
    

    五、append

    append 主要用于纵向追加数据。

    import pandas as pd
    df1=pd.DataFrame({'key':['a','b','a','b','b'],'value1':range(5)})
    df2=pd.DataFrame({'key':['a','c','c','c','c'],'value2':range(5)})
    df1.append(df2)
    
    # 重建索引
    df1.append(df2, ignore_index=True)
    df1.append(df2).reset_index(drop=True) # 同上
    

    六、combine

    conbine 可以通过使用函数,把两个 DataFrame 按列进行组合对比。

    注意:按列进行对比,而不是按行、按值等。

    1.使用语法

    df1.combine(df2, func, fill_value=None, overwrite=True)
    

    2.实操

    # 返回最小的那一列
    import pandas as pd
    df1 = pd.DataFrame({'A': [0, 0], 'B': [4, 4]})
    df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})
    
    # 整列比较
    take_smaller = lambda x, y: x if x.sum() < y.sum() else y
    df1.combine(df2, take_smaller)
    '''
       A  B
    0  0  3
    1  0  3
    '''
    
    # 对应位置的最小值
    import pandas as pd
    import numpy as np
    df1 = pd.DataFrame({'A': [5, 0], 'B': [2, 4]})
    df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})
    
    df1.combine(df2, np.minimum)
    '''
       A  B
    0  1  2
    1  0  3
    '''
    
    # 填充缺失值
    import pandas as pd
    import numpy as np
    df1 = pd.DataFrame({'A': [0, 0], 'B': [None, 4]})
    df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})
    
    df1.combine(df2, take_smaller, fill_value=-5)
    '''
       A    B
    0  0 -5.0
    1  0  4.0
    '''
    

    对于 DataFrame 中不存在的列,结果为 NaN

    # 参数 overwrite 默认为 True
    # 当 df 中存在、other 中不存在时,可以通过该参数确定是否使用 other 的值填充 df
    import pandas as pd
    import numpy as np
    df1 = pd.DataFrame({'A': [1, 1], 'B': [4, 4]})
    df2 = pd.DataFrame({'B': [3, 3], 'C': [1, 1], }, index=[1, 2])
    
    df1.combine(df2, take_smaller, overwrite=False)
    '''
         A    B   C
    0  1.0  NaN NaN
    1  1.0  3.0 NaN
    2  NaN  3.0 NaN
    '''
    

    返回最大值

    import pandas as pd
    import numpy as np
    x = pd.DataFrame({"A":[3,4],"B":[1,4]})
    y = pd.DataFrame({"A":[1,2],"B":[5,6]})
    x.combine(y, lambda a, b: np.where(a > b, a, b))
    '''
        A	B
    0	3	5
    1	4	6
    '''
    

    返回对应位置上的最大值

    # numpy.where 用法
    numpy.where(condition, x, y)
    # 满足条件(condition),输出x,不满足输出y
    

    七、combine_first

    实例方法 combine_first,它既不是行之间的连接,也不是列之间的连接。

    它为数据“打补丁”:用参数对象中的数据为调用者对象的缺失数据“打补丁”。

    import pandas as pd
    import numpy as np
    x = pd.DataFrame([[np.nan, 3., 5.], [-4.6, np.nan, np.nan],[np.nan, 7., np.nan]])
    y = pd.DataFrame([[-42.6, np.nan, -8.2], [-5., 1.6, 4]], index=[1, 2])
    
    # 如果x数据缺失,则用y数据填充
    x.combine_first(y)
    '''
         0    1    2
    0  NaN  3.0  5.0
    1 -4.6  NaN -8.2
    2 -5.0  7.0  4.0
    '''
    
    # 不存在的列直接用NaN替代
    df1 = pd.DataFrame({'A': [None, 0], 'B': [4, None]})
    df2 = pd.DataFrame({'B': [3, 3], 'C': [1, 1]}, index=[1, 2])
    df1.combine_first(df2)
    '''
         A    B    C
    0  NaN  4.0  NaN
    1  0.0  3.0  1.0
    2  NaN  3.0  1.0
    '''
    

    八、np.concatenate

    类似于 pd.concat 函数。

    import pandas as pd
    import numpy as np
    from pandas import Series, DataFrame
    
    arr1 = np.arange(9).reshape(3,3)
    arr2 = np.arange(9).reshape(3,3)
    
    # 默认 axis=0 纵向结合
    np.concatenate([arr1, arr2]) 
    '''
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8],
           [0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    '''
    # 横向结合
    np.concatenate([arr1, arr2], axis=1) 
    
    s1 = Series([1,2,3], index=['X','Y','Z'])
    s2 = Series([4,5], index=['A','B'])
    
    pd.concat([s1, s2])
    pd.concat([s1, s2], axis=1) # 缺失值会补齐为NaN
    

    参考链接:Pandas中合并数据的5个函数,各有千秋!

    参考链接:python 数据合并函数merge( )

    参考链接:【python】详解pandas库的pd.merge函数

    参考链接:python 合并(merge , concat , join , combine_first)

    参考链接:python pandas 合并数据函数merge join concat combine_first 区分

    参考链接:pandas.DataFrame.combine_first

    参考链接:pandas 之 combine 详解,如果 df 不存在、other 中存在,会如何处理

    参考链接:Pandas玩转数据(五) -- Concatenate和Combine

  • 相关阅读:
    BAT带队烧钱圈地华为们猛追云计算
    各浏览器的cookie的name个数/最大容量限制测试
    多备份:云端数据物流平台为企业提供云备份服务(通过增值服务盈利,数据备份相当于买保险)
    多备份CEO胡茂华:创业路上的五道坎
    蜡笔同步:同步通讯录,同步短信,用电脑发短信
    MIUI是小米的核心竞争力
    tggg
    Ubuntu 创建启动器
    TProcedure,TMethod,TNotifyEvent,TWndMethod的区别,并模拟点击按钮后发生的动作
    所有语言的Awesome
  • 原文地址:https://www.cnblogs.com/hider/p/15272095.html
Copyright © 2011-2022 走看看