• Pandas数据规整之合并


    数据合并

    Pandas提供了大量方法,能轻松的对Series,DataFrame执行合并操作

    • 按行合并
    1. 追加:append()
    2. 连接:concat() # 行列均可
    • 按列合并
    1. 复杂合并:merge()
    2. 按行索引合并:join()

    合并重叠数据(一个表为主,先填充再合并):combine_first()

    追加 append()

    ### series
    s = pd.Series([0, 1], index=['a', 'c'])
    s1 = pd.Series([2, 3, 4], index=['b', 'd', 'e'])
    s.append(s1)
    
    ### dataframe
    df = pd.DataFrame(np.random.randn(8, 4), columns = ['A','B','C','D'])
    s = df.loc[[3, 5]]
    # 追加合并
    df.append(s)
    df.append(s, ignore_index=True)  # 不使用追加表的索引,使用主表的默认索引
    
    ###DataFrame和Series追加合并
    # Series的行索引和Dataframe的列索引可以匹配上就可以追加一行,否则
    series的行索引充当dataframe的列索引
    # 必要参数 ignore_index=True
    s2 = pd.Series([1,2,3,4], index = ['A','B','C','D'])
    df.append(s2, ignore_index=True) 

    连接 .concat()

    ### 多个表按行或列合并
    s1 = pd.Series([0, 1], index=['a', 'c'])
    s2 = pd.Series([2, 3, 4], index=['b', 'd', 'e'])
    s3 = pd.Series([5, 6], index=['f', 'g'])
    # 返回series
    pd.concat([s1, s2, s3])
    # 返回dataframe
    pd.concat([s1, s2, s3], axis=1, sort=False)
    
    # 将 s1 和 s3 沿 0轴 连接创建 s4,这样 s4 和 s1 的 index 是有重复的。
    s4 = pd.concat([s1, s3])
    # 返回dataframe
    pd.concat([s1, s4], axis=1, join='outer', sort=False)  # 默认outer.并集
    pd.concat([s1, s4], axis=1, sort=False, join='inner')  # 交集
    
    # 将 n 个 Series 沿 0轴 连接起来,再赋予 n 个 keys 创建多层 Series。
    pd.concat([s1, s2, s3], keys=['one', 'two', 'three'])
    
    总结:
    series
    key来识别数据源自于哪张表,与ignore_index=True一起用的时候,不在显示keys
    axis=0时候,直接追加加索引和值返回series
    axis=1时候,join=outer,series的索引追加到行索引,series的值变为列索引的值,没有为nan,返回Dataframe
                join=inner,series的索引追加到行索引,series的值变为列索引的值,取交集,返回Dataframe
                
    DataFrame
    axis=0,追加到行,如果columns不同的时候也追加列
    axis=1,追加到列,如果行索引相同在相同行索引追加到不同列;行索引不同,追加行索引和列索引
    

    复杂合并 .merge()和.join()

    按列合并

    merge()函数用于复杂综合数据合并,操作复杂,功能强大

    join()是merge()的一个特殊用法,用于按索引合并,操作简单,功能单一

    # df1,姓名和分组
    df1 = pd.DataFrame({
        'name': ['张三', '李四', '王五', '赵六'],
        'group': ['DBA', 'PM','PM', 'HR']
    })
    # df2,姓名和入职时间
    df2 = pd.DataFrame({
        'name': ['李四', '赵六', '张三', '王五'],
        'date': [2004, 2008, 2012, 2014]
    })
    
    两个表必须有相关性,才有合并的需要
    以两个表相关的列(或行索引)为基准,合并
    
    方法1:使用查询和添加列进行表合并,比较麻烦,且行列如不完全对应容易出问题
    # 查询添加默认以行索引为基准对齐,所以需要把俩表相关列设为行索引
    df11 = df1.set_index('name').copy()
    df21 = df2.set_index('name').copy()
    df21['group'] = df11['group']
    df21.reset_index()
    
    方法2:合并两个对象,默认匹配相同过的列名,自动对齐合并
    要合并的样本量(行数)不同时,合并后的数据会自动扩展,不损失信息
    df3 = pd.merge(df1, df2)
    
    
    # df4,每个分组的领导,行数少
    df4 = pd.DataFrame({
        'group': ['DBA', 'PM', 'HR'],
        'leader': ['钱大', '孙二', '周三']
    })
    # 样本量(行数)不同时,合并后的数据会自动扩展,不损失信息
    pd.merge(df3, df4)
    
    
    df5 = pd.DataFrame({
        'group': ['DBA', 'DBA','PM', 'PM', 'HR', 'HR'],
        'skills': ['Linux', '数据库', 'Axuer RP', '社交','招聘', '组织']
    })
    pd.merge(df1, df5)
    
    
    两个表没有同名列时,如何合并
    两个对象没有同名列时,用left_on和right_on强制指定列名对应合并
    # df6,姓名2 username 和薪资
    df6 = pd.DataFrame({
        'username': ['王五', '张三', '赵六', '李四'],
        'salary': [10000, 160000, 7000, 120000]
    })
    pd.merge(df1, df6, left_on='name', right_on='username')
    pd.merge(df1, df6, left_on='name', right_on='username').drop('username', axis=1)  # 删除重复列
    

    按照行索引合并

    当要合并数据的行索引相关时,指定 merge() 函数的参数 left_index 与 right_index 的值为 True,就可以实现自动依照索引序号合并

    join()函数也能实现,写法更简单

    merge()的优势在于更灵活,尤其是当数据集索引值差别很大,数据合并又必须以其中一组数据的索引值为依据时

    # df1a,将df1的name列设为行索引  df2a,将df2的name列设为行索引
    df1a = df1.set_index('name')
    df2a = df2.set_index('name')
    按索引合并,最简单的方式 :join()
    df1a.join(df2a)
    df1a.join(df2a).reset_index()
    pd.merge(df1a, df2a, left_index=True, right_index=True)  # merge实现,同上
    
    两数据索引差异巨大,又必须以一个索引为主合并
    # df1a,姓名和分组,姓名为行索引, df6,姓名2和薪资
    # 指定一个表的行索引和另一个表的列为基准合并
    pd.merge(df1a, df6, left_index=True, right_on='username')
    
    
    两个对应列不完全重复的数据集的合并
    参数 how
    how='inner',交集,两个表共有的行
    how='outer',并集,两个表所有的行
    how='left',表1的行
    how='right',表2的行
    # df1,姓名和分组 ,df7,姓名和时间,姓名列不完全一致
    df7 = pd.DataFrame({'name':['张一', '李二', '赵六'], 'data':[2000,2001,2002]})
    pd.merge(df1, df7)
    pd.merge(df1, df7, how='inner')  # 默认,交集
    pd.merge(df1, df7, how='outer')  # 并集
    pd.merge(df1, df7, how='left')  # 以左表为基准
    pd.merge(df1, df7, how='right')  # 以右表为基准
    
    
    
    合并数据集中包含两个或以上相同列名时
    参数 on 指定用于合并的主键
    合并后的数据集中,之前相同的列名会被默认加上 _x 等后缀用于区分
    参数 suffixes 可以自定义后缀
    # df1,姓名和分组,df8,相同的姓名和分组
    df8 = pd.DataFrame({
        'name': ['张三', '王五', '赵六', '李四'],
        'group': ['code', 'VP','VP', 'code']
    })
    pd.merge(df1, df8, on='name')
    # 通过设置参数 suffixes 自定义后缀
    pd.merge(df1, df8, on='name', suffixes=['_L', '_R'])
    

      

    合并重叠数据(了解)

    有一类数据组合问题不能用简单的合并(merge)或连接(concatenation(concat))运算来处理。 如合并全部或部分重叠的两个数据集

    举例,我们使用NumPy的where函数,它表示一种等价于面向数组的if-else

    以a为基准合并,a的缺失值使用b填充

    先给a打补丁(用b填充a的缺失值,再合并)

    a = pd.Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan], index=['f', 'e', 'd', 'c', 'b', 'a'])
    b = pd.Series(np.arange(len(a), dtype=np.float64), index=['f', 'e', 'd', 'c', 'b', 'a'])
    b[-1] = np.nan
    
    ax = a.copy()
    ax.isnull()
    ax[ax.isnull()]  # 查询a的缺失值
    ax[ax.isnull()] = b  # a的缺失值用b填充(操作默认是索引对齐)
    
    
    
    Series有一个combine_first方法,实现的也是类似功能,
    除了用b填充a的缺失值,还带有pandas数据对齐的合并功能
    # :以a2为基准合并,a2缺失数据使用b2填充
    a2 = a[2:].copy()
    b2 = b[:-2].copy()
    方法1:使用原生方式打补丁(a2的缺失值使用b2填充)
    # 1:使用b2填充a2的缺失值(打补丁)
    a2[a2.isnull()] = b2
    # 2:合并数据
    a22 = a2.append(b2)
    # 3:去重,排序
    a22.index.duplicated()
    a22[~(a22.index.duplicated())].sort_index()
    
    方法2:使用combine_first方法,先打补丁,再合并,再去重排序
    a3 = a[2:].copy()
    a3.combine_first(b2)
    
    
    对于DataFrame,combine_first会在列上应用同样操作,可以将其看做:
    用传递对象中的数据为调用对象的缺失数据“打补丁”
    df11 = pd.DataFrame({'a': [1., np.nan, 5., np.nan], 'b': [np.nan, 2., np.nan, 6.], 'c': range(2, 18, 4)})
    df21 = pd.DataFrame({'a': [5., 4., np.nan, 3., 7.], 'b': [np.nan, 3., 4., 6., 8.]})
    df11.combine_first(df21)  # 以df11为基准,先填充缺失值(用df21的值填充df11),再合并(df21的多余行列合并到df11上)
    df21.combine_first(df11)  # 以df21为基准,先填充(用df11的值填充df21),再合并
    

      

      

      

    本文为原创文章,转载请标明出处
  • 相关阅读:
    数据库设计 一对多 多对多 无限级菜单 设计方法
    线程创建的四种方式
    Linux常用指令---grep(搜索过滤)
    Netty4实战
    linux查找日志技巧
    javascript---关于字符串和数组的方法
    angularJs---route
    JavaScript---详解scroll
    JavaScript--location
    socket中 emit和on的写法
  • 原文地址:https://www.cnblogs.com/harden13/p/13528001.html
Copyright © 2020-2023  润新知