将多个DataFrame与偶尔的重叠合并

时间:2019-01-29 17:34:25

标签: python pandas dataframe

我有多个从CSV文件读取的子DataFrame,我想使用pandas将它们合并为一个大DataFrame。

我的问题是,单独的子DataFrame中的某些列显示重叠。如果确实如此,则需要将这些值插入最终DataFrame中的正确位置。

通常,所有子DataFrame都有一个ID列-所有这些DataFrame的所有set值中的ID应该合并到最后一个大DataFrame的ID列中

为每个ID分配了一个特定的CODE,这在所有子DataFrame中都是一致的,因此,由于值应保持不变,因此有可能总是被覆盖。

我已经尝试了每种方式,mergejoinconcat,甚至是普通的旧循环和索引(带有索引列),都没有命名,但是,徒劳无功。

我想补充一点,有些方法会创建带有后缀的新列-但我的意图是将重叠列中的所有值合并到一个列中,所以这不是一个选择/

以下是一些示例数据:

import pandas as pd
import numpy as np

np.random.seed(42)

df_1 = pd.DataFrame({
    'ID':[3,4,5,6],
    'CODE':[2,2,5,4],
    'M1':np.random.rand(4),
    'M2':np.random.rand(4)    
})

df_2 = pd.DataFrame({
    'ID':[8,9,10],
    'CODE':[7,2,4],
    'M1':np.random.rand(3),
    'M2':np.random.rand(3)    
})


df_3 = pd.DataFrame({
    'ID':[3,4,5,6],
    'CODE':[2,2,5,4],
    'M3':np.random.rand(4),
    'M4':np.random.rand(4)    
})

df_4 = pd.DataFrame({
    'ID':[8,9,10],
    'CODE':[7,2,4],
    'M3':np.random.rand(3),
    'M4':np.random.rand(3)    
})

df_5 = pd.DataFrame({
    'ID':[8,9,10],
    'CODE':[7,2,4],
    'M5':np.random.rand(3),
    'M6':np.random.rand(3)    
})

使用mergehow="outer"可以合并df_1df_2df_3,结果是我需要的。

ID  CODE    M1  M2  M3  M4
0   3   2   0.374540    0.156019    0.181825    0.431945
1   4   2   0.950714    0.155995    0.183405    0.291229
2   5   5   0.731994    0.058084    0.304242    0.611853
3   6   4   0.598658    0.866176    0.524756    0.139494
4   8   7   0.601115    0.969910    NaN         NaN
5   9   2   0.708073    0.832443    NaN         NaN
6   10  4   0.020584    0.212339    NaN         NaN

但是添加df_4后,数据将被追加到下面,而不是被插入正确的位置(因此,在这种情况下将不会有NaN):

    ID  CODE      M1          M2          M3          M4
0   3   2   0.374540    0.156019    0.181825    0.431945
1   4   2   0.950714    0.155995    0.183405    0.291229
2   5   5   0.731994    0.058084    0.304242    0.611853
3   6   4   0.598658    0.866176    0.524756    0.139494
4   8   7   0.601115    0.969910    NaN         NaN
5   9   2   0.708073    0.832443    NaN         NaN
6   10  4   0.020584    0.212339    NaN         NaN
7   8   7   NaN         NaN        0.292145     0.785176
8   9   2   NaN         NaN        0.366362     0.199674
9   10  4   NaN         NaN        0.456070     0.514234

最后,在此示例中组合所有DataFrame会产生以下结果:

    ID  CODE      M1          M2          M3          M4     M5         M6
0   3   2   0.374540    0.156019    0.181825    0.431945    NaN         NaN
1   4   2   0.950714    0.155995    0.183405    0.291229    NaN         NaN
2   5   5   0.731994    0.058084    0.304242    0.611853    NaN         NaN
3   6   4   0.598658    0.866176    0.524756    0.139494    NaN         NaN
4   8   7   0.601115    0.969910    0.292145    0.785176    0.592414    0.170524
5   9   2   0.708073    0.832443    0.366362    0.199674    0.046450    0.065051
6   10  4   0.020584    0.212339    0.456070    0.514234    0.607544    0.948885

1 个答案:

答案 0 :(得分:1)

合并具有相同ID和代码的数据帧并将其连接起来。

pd.concat([df_1.merge(df_3, how = 'outer'),df_2.merge(df_4, how = 'outer').merge(df_5, how = 'outer')], sort = True)

    ID  CODE    M1      M2          M3          M4          M5          M6
0   3   2   0.374540    0.156019    0.181825    0.431945    NaN         NaN
1   4   2   0.950714    0.155995    0.183405    0.291229    NaN         NaN
2   5   5   0.731994    0.058084    0.304242    0.611853    NaN         NaN
3   6   4   0.598658    0.866176    0.524756    0.139494    NaN         NaN
4   8   7   0.601115    0.969910    0.292145    0.785176    0.592415    0.170524
5   9   2   0.708073    0.832443    0.366362    0.199674    0.046450    0.065052
6   10  4   0.020584    0.212339    0.456070    0.514234    0.607545    0.948886

另一个使用groupby的解决方案。在轴0上连接所有数据帧,在ID,CODE和first()上分组,返回第一个非NaN值。

dfs = [df_1, df_2, df_3, df_4, df_5]

pd.concat(dfs, sort = False).groupby(['CODE', 'ID']).first().sort_index(level = 1).reset_index()