【问题标题】:Concat a list of pandas data frames with a mixture of the same and different column names连接具有相同和不同列名的 pandas 数据帧列表
【发布时间】:2018-10-12 02:12:47
【问题描述】:

我有一个要合并到一个数据框的数据框列表

列表中具有相同列名的数据框具有不同的索引,反之亦然。每个数据框有 1 行 80 列,列表的总长度为 8000 个数据框。

这是我的数据框列表的缩小示例:

import pandas as pd

u = pd.DataFrame(data=[[1, 2, '111']], columns = ['a', 'b', 'id'])
u = u.set_index('id')

v = pd.DataFrame(data=[[3, 4, '222']], columns = ['a', 'b', 'id'])
v = v.set_index('id')

w = pd.DataFrame(data=[[5, 6, '333']], columns = ['a', 'b', 'id'])
w = w.set_index('id')

x = pd.DataFrame(data=[[7, 8, '444']], columns = ['a', 'b', 'id'])
x = x.set_index('id')

y = pd.DataFrame(data=[[9, 10, '111']], columns = ['c', 'd', 'id'])
y = y.set_index('id')

z = pd.DataFrame(data=[[11, 12, '222']], columns = ['c', 'd', 'id'])
z = z.set_index('id')

list_df = [u, v, w, x, y, z]

如何创建一个如下所示的合并表:

id    a     b    c    d
--------------------------
111   1.0   2.0  9.0  10.0
222   3.0   4.0  11.0 12.0
333   5.0   6.0  NaN  NaN
444   7.0   8.0  NaN  NaN

目前,由于我列表的大小,我一直在使用pd.concat。但是,pd.concat(list_df, axis = 0) 给出:

id    a     b    c    d
--------------------------
111   1.0   2.0  NaN  NaN
222   3.0   4.0  NaN  NaN
333   5.0   6.0  NaN  NaN
444   7.0   8.0  NaN  NaN
111   NaN   NaN  9.0  10.0
222   NaN   NaN  11.0 12.0

pd.concat(list_df, axis = 1) 给出:

id    a    b    a    b    a    b    a    b    c    d    c    d
----------------------------------------------------------------
111   1.0  2.0  NaN  NaN  NaN  NaN  NaN  NaN  9.0  10.0 NaN  NaN
222   NaN  NaN  3.0  4.0  NaN  NaN  NaN  NaN  NaN  NaN  11.0 12.0
333   NaN  NaN  NaN  NaN  5.0  6.0  NaN  NaN  NaN  NaN  NaN  NaN 
444   NaN  NaN  NaN  NaN  NaN  NaN  7.0  8.0  NaN  NaN  NaN  NaN

【问题讨论】:

    标签: python pandas indexing


    【解决方案1】:

    应该这样做:

    pd.concat([u, v, w, x, y, z], sort=False).set_index('id').groupby(level=0).first()
    

    产量:

           a    b     c     d
    id                       
    111  1.0  2.0   9.0  10.0
    222  3.0  4.0  11.0  12.0
    333  5.0  6.0   NaN   NaN
    444  7.0  8.0   NaN   NaN
    

    注意,您不需要为每个数据帧单独set_index()

    说明:

    您可以使用关键字sort=False 将数据帧列表传递给pd.concat(),这是pandas 0.23.0 版中的新功能,因为之前的行为是默认IIUC 排序(请参阅文档here)。然后,您可以使用set_index('id') 设置连接数据帧的索引。最后,您可以groupby(level=0) 将数据帧按其级别 0 索引 ('id') 进行分组,并通过 first() 为每行获取第一个非 NaN 值。

    【讨论】:

    • 甜蜜的解决方案。稍微解释一下就可以学到新东西了。另外,我在执行concat() got an unexpected keyword argument 'sort' 时遇到了这个错误
    • 对于旧版本的 pandas,只需删除排序关键字。
    • 为我的回答添加了解释。
    【解决方案2】:

    将具有相同列的 dfs 保持在一起,然后应用外连接

    import pandas as pd
    
    u = pd.DataFrame(data=[[1, 2, '111']], columns = ['a', 'b', 'id'])
    u = u.set_index('id')
    
    v = pd.DataFrame(data=[[3, 4, '222']], columns = ['a', 'b', 'id'])
    v = v.set_index('id')
    
    w = pd.DataFrame(data=[[5, 6, '333']], columns = ['a', 'b', 'id'])
    w = w.set_index('id')
    
    x = pd.DataFrame(data=[[7, 8, '444']], columns = ['a', 'b', 'id'])
    x = x.set_index('id')
    
    y = pd.DataFrame(data=[[9, 10, '111']], columns = ['c', 'd', 'id'])
    y = y.set_index('id')
    
    z = pd.DataFrame(data=[[11, 12, '222']], columns = ['c', 'd', 'id'])
    z = z.set_index('id')
    
    list_df = [u, v, w, x]
    df=pd.concat(list_df, axis = 0)
    df2=pd.concat([y,z], axis = 0)
    df.join(df2, how='outer')
    

    输出

        a   b   c       d
    id              
    111 1   2   9.0     10.0
    222 3   4   11.0    12.0
    333 5   6   NaN     NaN
    444 7   8   NaN      NaN
    

    【讨论】:

      猜你喜欢
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 2013-05-18
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 2018-06-20
      相关资源
      最近更新 更多