合并数据框而不复制列

时间:2019-08-03 04:04:14

标签: python pandas dataframe merge

我有3个具有不同结构的数据框,其中一个包含2个与其他两个链接的键:

df1 = id1  id2    df2 = id1  a   b1  c1  c2    df3 = id2 a   b1   b2   c1
      1                 1    1a  1b1 1c1 1c2         11  11a 11b1 11b2 11c1
           11           2    2a  2b1 2c1 2c2         12  12a 12b1 12b2 12c1
           12           3    3a  3b1 3c1 3c2         13  13a 13b1 13b2 13c1
           13                                        14  14a 14b1 14b2 14c1
      2                                              21  21a 21b1 21b2 21c1
           21                                        22  22a 22b1 22b2 22c1
           22                                        23  23a 23b1 23b2 23c1
                                                     31  31a 31b1 31b2 31c1

然后我将df1df2合并:

df1 = pd.merge(df1, df2, on='id1', how='left')

df1 = id1  id2  a   b1  c1  c2
      1         1a  1b1 1c1 1c2
           11   nan nan nan nan
           12   nan nan nan nan
           13   nan nan nan nan
      2         2a  2b1 2c1 2c2
           21   nan nan nan nan
           22   nan nan nan nan

但是当我与df3合并时,我有:

df1 = pd.merge(df1, df3, on='id2', how='left')

df1 = id1  id2   a_x  b1_x  c1_x  c2   a_y  b1_y  b2   c1_y  
      1          1a   1b1   1c1   1c2
           11    nan  nan   nan   nan  11a  11b1  11b2 11c1
           12    nan  nan   nan   nan  12a  12b1  12b2 12c1
           13    nan  nan   nan   nan  13a  13b1  13b2 13c1
      2          2a   2b1   2c1   2c2
           21    nan  nan   nan   nan  21a  21b1  21b2 21c1
           22    nan  nan   nan   nan  22a  22b1  22b2 22c1
简而言之,当要合并的数据帧之间有重叠的列时,该方法将创建一个新的带有砜的列。但是,我希望这些值在重合的列中被替换。

我想要得到的是这样的:

df1 = id1  id2   a    b1    c1    c2   b2   
      1          1a   1b1   1c1   1c2
           11    11a  11b1  11c1       11b2
           12    12a  12b1  12c1       12b2
           13    13a  13b1  13c1       13b2
      2          2a   2b1   2c1   2c2
           21    21a  21b1  21c1       21b2
           22    22a  22b1  22c1       22b2

在第二次合并之前,我也尝试过fillna(''),但结果相同。

2 个答案:

答案 0 :(得分:1)

尝试如下

df1 = pd.merge(df1, df3, on='id2', how='left')
df1['a']=df1['a_y'].fillna(df1['a_x'])
df1['b']=df1['b_y'].fillna(df1['b_x'])
df1['c1']=df1['c1_y'].fillna(df1['c1_x'])

答案 1 :(得分:0)

在大熊猫中,这是一个非常困难的问题。我也一直试图处理它。一种选择是为每个单独的合并创建一个单独的数据框,然后将它们合并在一起。我认为这不是“替代方法-y”:

df_m1 = pd.merge(df1, df2, on='id1', how='inner')  # note it's an inner merge
df_m2 = pd.merge(df1, df3, on='id2', how='inner')
df1 = pd.concat([df_m1, df_m2])

但是,会有一个问题:如果df1中有某些行无法与您想要保留的df2df3合并,它们将不会停留在上面的示例中。您必须手动添加它们。在这一点上,如果您可以手动添加具有不在df_m1df_m2中的索引的行,那将是很好的选择,但是问题是合并不能保存索引(请参阅:{ {3}}),这的确使这个问题更加复杂了。

因此您可以将以上内容修改为:

df_m1 = pd.merge(df1, df2, on='id1', how='inner')  # note it's an inner merge
df_m2 = pd.merge(df1, df3, on='id2', how='inner')
df1 = pd.concat([df_m1, df_m2, df1[~df1.id1.isin(df2.id1) & ~df1.id2.isin(df3.id2)])

如果有更好的方法来完成最后一部分,那就太好了。如果您还需要合并任意数量的数据帧,则以上内容是可循环的。


编辑:或者,由于通常情况下,当您要合并3个以上的数据框时,将有助于使用索引完成最后一部分,因此您可以执行以下操作:

df1['old_index'] = df1.index  # this will let you keep the index
df_m1 = pd.merge(df1, df2, on='id1', how='inner')  # note it's an inner merge
df_m2 = pd.merge(df1, df3, on='id2', how='inner')
df_other = df1[~df1.old_index.isin(pd.concat([df_m1, df_m2]).old_index)]


df1 = pd.concat([df_m1, df_m2, df_other])

这将更容易陷入循环。