【问题标题】:Merging multiple Pandas data-frames on multiple columns在多列上合并多个 Pandas 数据框
【发布时间】:2020-04-18 19:11:50
【问题描述】:

我正在尝试将其他数据帧(DF_BDF_C)合并到 DF_A 上以等于 DF_D

将附加数据帧绑定到 DF_A 的唯一方法是通过列 B_2,因此我尝试将它们合并到 B_2。我在下面尝试了这段代码来合并第一个附加数据帧 (DF_B)。

DF_D = pd.merge(DF_A, DF_B, how='left', on='B_2') 

这几乎奏效了,但它正在创建额外的列。

所以我认为添加left_on= 可能有效,但它没有。

DF_D = pd.merge(DF_A, DF_B, how='left', left_on=['B_2','C_3', 'D_4'])


我正在寻找一种在主数据帧上写入额外数据帧的方法,直到 DF_D 被填写。另外,我希望 DF_D 保留所有其他行和原始列/名称,即使在合并期间没有匹配项。

原始主数据框 A:

     A_1   B_2 C_3   D_4
0  03/17  3001          
1  03/17  2002   L  BLUE
2  03/17  3777          
3  04/17  5555          
4  04/17  3232          
5  04/17  5000          
6  04/17  5151          
7  05/17  2212   S   RED

附加数据框 B:

    B_2 C_3    D_4
0  3001   M   GRAY
1  3131   S   BLUE
2  3333  XS  GREEN
3  3232   L   PINK
4  3000   M    RED

像这样使用:

DF_1 = pd.merge(DF_A, DF_B, how='left', on='B_2')

附加数据框 C:

    B_2 C_3    D_4
0  5151   S   BLUE
1  5545   M   PINK
2  5555  XL    RED
3  5222   L   GRAY
4  5112   S  GREEN

像这样使用:

DF_D = pd.merge(DF_1, DF_C, how='left', on='B_2')

结果,最终 DF_D:

     A_1   B_2 C_3   D_4
0  03/17  3001   M  GRAY
1  03/17  2002   L  BLUE
2  03/17  3777          
3  04/17  5555  XL   RED
4  04/17  3232   L  PINK
5  04/17  5000          
6  04/17  5151   S  BLUE
7  05/17  2212   S   RED

【问题讨论】:

    标签: python-3.x pandas merge


    【解决方案1】:

    听起来你想要这样的东西:

    # Make DF_A look like DF_B and DF_C. Same columns, no missing values.
    DF_A_filt = DF_A[['B_2', 'C_3', 'D_4']]
    DF_A_filt = DF_A_filt[DF_A_filt['C_3'].notnull()]
    
    # Put all the "feature" data together.
    df_data = pd.concat([DF_A_filt, DF_B, DF_C], ignore_index=True)
    
    # Drop duplicates by the join key B_2 to keep only the first match.
    # This will prefer DF_A, then DF_B, then DF_C.
    df_data = df_data.drop_duplicates('B_2')
    
    # Merge the features back onto the keys by B_2.
    DF_D = DF_A[['A_1', 'B_2']].merge(df_data, on='B_2', how='left')
    

    一路上的数据是这样的:

    DF_A_filt                                                                                                                                                                                                                           
    #     B_2 C_3   D_4
    # 1  2002   L  BLUE
    # 7  2212   S   RED
    
    df_data
    #      B_2 C_3    D_4
    # 0   2002   L   BLUE
    # 1   2212   S    RED
    # 2   3001   M   GRAY
    # 3   3131   S   BLUE
    # 4   3333  XS  GREEN
    # 5   3232   L   PINK
    # 6   3000   M    RED
    # 7   5151   S   BLUE
    # 8   5545   M   PINK
    # 9   5555  XL    RED
    # 10  5222   L   GRAY
    # 11  5112   S  GREEN
    
    DF_D
         A_1   B_2  C_3   D_4
    # 0  03/17  3001    M  GRAY
    # 1  03/17  2002    L  BLUE
    # 2  03/17  3777  NaN   NaN
    # 3  04/17  5555   XL   RED
    # 4  04/17  3232    L  PINK
    # 5  04/17  5000  NaN   NaN
    # 6  04/17  5151    S  BLUE
    # 7  05/17  2212    S   RED
    

    【讨论】:

    • 谢谢@mcskinner - 这解决了我的问题。感谢您沿途布置数据流。您的回答帮助我更好地理解如何处理数据。干杯!
    【解决方案2】:

    考虑为 dfA 构建一个合并数据框列表,然后在排好序的列中使用 bfill,然后是 concat + groupby + first

    # MERGE EACH df TO dfA
    df_list = [dfA.merge(df, on='___B_2___', how='left', suffixes=['','_']) 
                  for df in [dfB, dfC]]
    
    # SORT BY COLUMN NAMES THEN bfill BY ROW
    df_list = [df.reindex(sorted(df.columns.to_list()), axis='columns') 
                 .bfill(axis=1) for df in df_list]
    
    # CONCAT + GROUPBY + FIRST
    final_df = (pd.concat(df_list)
                  .reindex(dfA.columns.to_list(), axis='columns')
                  .groupby(['A_1', 'B_2'], as_index = False, sort=False)
                  .first())
    
    print(final_df)
    #          A_1   B_2  C_3   D_4
    # 0  __03/17__  3001    M  GRAY
    # 1  __03/17__  2002    L  BLUE
    # 2  __03/17__  3777  NaN   NaN
    # 3  __04/17__  5555   XL   RED
    # 4  __04/17__  3232    L  PINK
    # 5  __04/17__  5000  NaN   NaN
    # 6  __04/17__  5151    S  BLUE
    # 7  __05/17__  2212    S   RED
    

    【讨论】:

    • 嗨冻糕,谢谢你的回答。我确定您的解决方案可以正常工作,但我能够先通过 mcskinner 的回答完成我的任务。干杯!
    猜你喜欢
    • 1970-01-01
    • 2019-12-09
    • 2020-11-02
    • 2017-06-08
    • 2022-11-27
    • 2017-10-05
    • 1970-01-01
    • 2019-11-19
    相关资源
    最近更新 更多