【问题标题】:How to merge multiple pandas dataframes into one original dataframe in the most efficient way?如何以最有效的方式将多个 pandas 数据帧合并为一个原始数据帧?
【发布时间】:2020-09-28 13:40:56
【问题描述】:

如何以最有效的方式将 4 个 pandas 数据帧合并为一个原始数据帧? 下面显示了原始数据框df,其中CC1CC2CC3CC4 的4 列需要使用df1df2df3df4 中的相应列进行更新.

所有数据帧的公共列是TDPD

编辑

df

TD   PD  CC1    CC2    CC3    CC4    A     B     C
10   1   Null   Null   Null   Null   1     1     0
10   2   Null   Null   Null   Null   0     1     1
10   3   Null   Null   Null   Null   Null  2     Null
20   1   Null   Null   Null   Null   Null  0     1
20   4   Null   Null   Null   Null   2     Null  Null
30   1   Null   Null   Null   Null   4     0     2
30   3   Null   Null   Null   Null   8     Null  5
30   5   Null   Null   Null   Null   Null  1     1
40   2   Null   Null   Null   Null   0     0     0

df1

TD   PD   CC1
10   2     0
20   1     5
20   4     2
30   3    10

df2

TD   PD   CC2
10   1     15
10   2     10
20   4     20

df3

TD   PD   CC3
10   3     0
20   4     5
30   1     9

df4

TD   PD   CC4
20   4     0
30   1     15
30   3     20

合并后的预期输出如下:

df

TD   PD  CC1    CC2    CC3    CC4   A      B     C
10   1   Null   15    Null   Null   1      1     0
10   2    0     10    Null   Null   0      1     1
10   3   Null  Null    0     Null   Null   2     Null
20   1    5    Null   Null   Null   Null   0     1
20   4    2     20     5      0     2      Null  Null
30   1   Null  Null    9      15    4      0     2
30   3    10   Null   Null    20    8      Null  5
30   5   Null   Null   Null  Null   Null   1     1
40   2   Null   Null   Null  Null   0      0     0

dfABC)中的其他额外列不受影响。 此外,df1、df2、df3 和 df4 中的总行数不等于 df 中的行数。如何以最快的方式实现这一点,是否可以仅在一个语句中完成,还是必须在此处使用 4 个不同的语句?

非常感谢任何帮助。非常感谢。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    在列表推导中使用concat 来创建MultiIndex by TDPD 用于外部连接 by DataFrame.set_index 然后DataFrame.reset_index 用于MultiIndex 到列:

    dfs = [df1, df2, df3, df4]
    dfnew = pd.concat([x.set_index(['TD', 'PD']) for x in dfs], axis=1).reset_index()
    print (dfnew)
       TD  PD   CC1   CC2  CC3   CC4
    0  10   1   NaN  15.0  NaN   NaN
    1  10   2   0.0  10.0  NaN   NaN
    2  10   3   NaN   NaN  0.0   NaN
    3  20   1   5.0   NaN  NaN   NaN
    4  20   4   2.0  20.0  5.0   0.0
    5  30   1   NaN   NaN  9.0  15.0
    6  30   3  10.0   NaN  NaN  20.0
    
    
    df = df.combine_first(dfnew)
    

    编辑:错误意味着TDPD 组合中有重复项。

    #changed data for simulate error
    print (df1)
       TD  PD  CC1
    0  10   2    0
    1  20   4    5 <- duplicates
    2  20   4    2 <- duplicates
    3  20   4   10 <- duplicates
    

    一个想法是删除重复的行,因此输出中只有第一个值:

    dfs = [df1, df2, df3, df4]
    dfnew = pd.concat([x.drop_duplicates(['TD','PD']).set_index(['TD', 'PD']) 
                       for x in dfs], axis=1).reset_index()
    print (dfnew)
       TD  PD  CC1   CC2  CC3   CC4
    0  10   1  NaN  15.0  NaN   NaN
    1  10   2  0.0  10.0  NaN   NaN
    2  10   3  NaN   NaN  0.0   NaN
    3  20   4  5.0  20.0  5.0   0.0 <- first value 5
    4  30   1  NaN   NaN  9.0  15.0
    5  30   3  NaN   NaN  NaN  20.0
    

    另一个想法是聚合的,例如sum:

    dfnew = pd.concat([x.groupby(['TD', 'PD']).sum() for x in dfs], axis=1).reset_index()
    print (dfnew)
       TD  PD   CC1   CC2  CC3   CC4
    0  10   1   NaN  15.0  NaN   NaN
    1  10   2   0.0  10.0  NaN   NaN
    2  10   3   NaN   NaN  0.0   NaN
    3  20   4  17.0  20.0  5.0   0.0 <- summed values - 17
    4  30   1   NaN   NaN  9.0  15.0
    5  30   3   NaN   NaN  NaN  20.0
    

    【讨论】:

    • 比合并4次好多了。 +1
    • @jezrael 如果原始df 中的行数超过所有其他 4 个 dfs 中的所有行的总和怎么办?这个解决方案还会有效吗?另外,如果原始df中还有其他列怎么办?
    • @Prachi - 你能改变这种情况的解决方案吗?
    • @jezrael 我已经编辑了我的问题。您现在可以看看并提供解决方案吗?
    • @Prachi - 你能检查编辑的答案吗?重命名了新的 DataFrame 并添加了最后一行代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 2019-05-31
    • 1970-01-01
    • 2020-03-03
    • 2021-10-18
    • 2018-01-31
    • 2019-10-05
    相关资源
    最近更新 更多