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

  • 相关阅读:
    ant 软件包不存在报错
    在 Internet Explorer 中使用 Windows 窗体控件
    智能客户端
    Back to the Future with Smart Clients
    "Automation 服务器不能创建对象" 的解决方案
    Top 10 Reasons for Developers to Create Smart Clients
    Updater Application Block for .NET
    Smart Client Application Model and the .NET Framework 1.1
    Security and Versioning Models in the Windows Forms Engine Help You Create and Deploy Smart Clients
    智能客户端技术总结(二)
  • 原文地址:https://www.cnblogs.com/hider/p/15272095.html
Copyright © 2011-2022 走看看