代码之家  ›  专栏  ›  技术社区  ›  mortysporty

连接两个数据帧,并从数据帧中获取具有索引的新帧

  •  0
  • mortysporty  · 技术社区  · 5 年前

    我希望两个数据帧连接两个具有不同索引的数据帧,并返回一个新数据帧,其中包含匹配的两个帧的索引。

    df_a 包含许多模拟的结果值。 df_b ,对于每个组和三个不同的“级别”,包含我们想要检索的结果模拟值。最终输出应该是一个包含每个组、级别和匹配模拟的数据帧。例如,对于“Group_1”,“Level_1”模拟“Sim_5”就是我们想要的模拟。

    df_a = pd.DataFrame({'Group_1': [5, 2, 3, 4, 1],
                         'Group_2': [1, 4, 3, 2, 5],
                         'Group_3': [2, 1, 5, 4, 3]}, 
                        index=['Sim_1', 'Sim_2', 'Sim_3', 'Sim_4', 'Sim_5'])
    df_b = pd.DataFrame({'Group_1': [1, 2, 4],
                         'Group_2': [2, 5, 1],
                         'Group_3': [3, 2, 4]}, 
                        index=['Level_1', 'Level_2', 'Level_3'])
    
    # Expected output
    df_c = pd.DataFrame(data=['Sim_5', 'Sim_2', 'Sim_4', 'Sim_4', 'Sim_5', 'Sim_1', 'Sim_5', 'Sim_1', 'Sim_4'],
                        index=pd.MultiIndex.from_product([['Group_1', 'Group_2', 'Group_3'], ['Level_1', 'Level_2', 'Level_3']]))
    
    Out[54]: 
                         0
    Group_1 Level_1  Sim_5
            Level_2  Sim_2
            Level_3  Sim_4
    Group_2 Level_1  Sim_4
            Level_2  Sim_5
            Level_3  Sim_1
    Group_3 Level_1  Sim_5
            Level_2  Sim_1
            Level_3  Sim_4
    

    有人能想出一个好办法来实现这一点吗?我可能能够“暴力破解”一些东西,但我更喜欢一个干净的实现。

    2 回复  |  直到 5 年前
        1
  •  1
  •   jezrael    5 年前

    使用内部 DataFrame.merge 通过以下方式使用未象牙化的值 DataFrame.melt ,转换为 MultiIndex 通过 DataFrame.set_index ,删除索引名称 DataFrame.rename_axis ,转换为一列 DataFrame 通过 Series.to_frame 并排序 多索引 :

    df = (df_a.reset_index().melt('index')
               .merge(df_b.reset_index().melt('index')
                      , on=['variable','value'])
               .set_index(['variable','index_y'])['index_x']
               .rename_axis((None, None))
               .to_frame(0)
               .sort_index())
    print (df)
                         0
    Group_1 Level_1  Sim_5
            Level_2  Sim_2
            Level_3  Sim_4
    Group_2 Level_1  Sim_4
            Level_2  Sim_5
            Level_3  Sim_1
    Group_3 Level_1  Sim_5
            Level_2  Sim_1
            Level_3  Sim_4
    
        2
  •  1
  •   Henry Yik    5 年前

    可能不是最干净的,但这只是一种方法:

    a = (df_a.reset_index().melt(id_vars="index").set_index(["variable","value"]))
    b = (df_b.reset_index().melt(id_vars="index").set_index(["variable","value"]))
    
    print (b.join(a, lsuffix="_a", rsuffix="_b").reset_index(level=1, drop=True)
            .set_index('index_b', append=True).sort_index())
    
                    index_a index_b
    variable value                 
    Group_1  1      Level_1   Sim_5
             2      Level_2   Sim_2
             4      Level_3   Sim_4
    Group_2  1      Level_3   Sim_1
             2      Level_1   Sim_4
             5      Level_2   Sim_5
    Group_3  2      Level_2   Sim_1
             3      Level_1   Sim_5
             4      Level_3   Sim_4