【问题标题】:Merge multi-indexed with single-indexed data frames in pandas将多索引与熊猫中的单索引数据框合并
【发布时间】:2012-12-18 10:05:03
【问题描述】:

我有两个数据框。 df1 是多索引的:

                value
first second    
a     x         0.471780
      y         0.774908
      z         0.563634
b     x         -0.353756
      y         0.368062
      z         -1.721840

和df2:

      value
first   
a     10
b     20

如何仅将两个数据框与一个多索引(在本例中为“第一个”索引)合并?期望的输出是:

                value1      value2
first second    
a     x         0.471780    10
      y         0.774908    10
      z         0.563634    10
b     x         -0.353756   20
      y         0.368062    20
      z         -1.721840   20

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你可以使用get_level_values:

    firsts = df1.index.get_level_values('first')
    df1['value2'] = df2.loc[firsts].values
    

    注意:您几乎在这里执行join(除了 df1 是 MultiIndex)...所以可能有更简洁的方式来描述这个...

    .

    在一个例子中(类似于你所拥有的):

    df1 = pd.DataFrame([['a', 'x', 0.123], ['a','x', 0.234],
                        ['a', 'y', 0.451], ['b', 'x', 0.453]],
                       columns=['first', 'second', 'value1']
                       ).set_index(['first', 'second'])
    df2 = pd.DataFrame([['a', 10],['b', 20]],
                       columns=['first', 'value']).set_index(['first'])
    
    firsts = df1.index.get_level_values('first')
    df1['value2'] = df2.loc[firsts].values
    
    In [5]: df1
    Out[5]: 
                  value1  value2
    first second                
    a     x        0.123      10
          x        0.234      10
          y        0.451      10
    b     x        0.453      20
    

    【讨论】:

    • 你可以几乎像这样合并:df1.merge(df2, left_on=df1.index.get_level_values('first'), right_on=df2.index.get_level_values('first'))
    • 此方法在给定的示例中运行良好,但我想知道当某些单索引不同时会发生什么(例如,一个中有多个元素)
    • 从v.0.23开始,可以使用left_on='name_of_index_level'; IOW,@AndyHayden 的示例简化为 df1.merge(df2, left_on='first', right_on='first')
    【解决方案2】:

    由于.ix 语法是重新索引的强大快捷方式,但在这种情况下,您实际上并没有进行任何组合的行/列重新索引,这可以更优雅地完成(对于我不起眼的味蕾),只需使用重新索引:

    海登的准备:

    df1 = pd.DataFrame([['a', 'x', 0.123], ['a','x', 0.234],
                        ['a', 'y', 0.451], ['b', 'x', 0.453]],
                       columns=['first', 'second', 'value1']
                       ).set_index(['first', 'second'])
    df2 = pd.DataFrame([['a', 10],['b', 20]],
                       columns=['first', 'value']).set_index(['first'])
    

    那么这在 iPython 中是这样的:

    In [4]: df1
    Out[4]: 
                  value1
    first second        
    a     x        0.123
          x        0.234
          y        0.451
    b     x        0.453
    
    In [5]: df2
    Out[5]: 
           value
    first       
    a         10
    b         20
    
    In [7]: df2.reindex(df1.index, level=0)
    Out[7]: 
                  value
    first second       
    a     x          10
          x          10
          y          10
    b     x          20
    
    In [8]: df1['value2'] = df2.reindex(df1.index, level=0)
    
    In [9]: df1
    Out[9]: 
                  value1  value2
    first second                
    a     x        0.123      10
          x        0.234      10
          y        0.451      10
    b     x        0.453      20
    

    在重新索引方法中必须使用什么级别的助记符: 它说明了您已经在较大索引中涵盖的级别。 因此,在这种情况下,df2 已经覆盖了 df1.index 的级别 0。

    【讨论】:

      【解决方案3】:

      根据the documentation,从pandas 0.14 开始,您可以简单地加入单索引和多索引数据帧。它将匹配公共索引名称。 how 参数在 'inner''outer' 上按预期工作,但有趣的是它似乎在 'left''right' 上相反(这可能是一个错误吗?)。

      df1 = pd.DataFrame([['a', 'x', 0.471780], ['a','y', 0.774908], ['a', 'z', 0.563634],
                          ['b', 'x', -0.353756], ['b', 'y', 0.368062], ['b', 'z', -1.721840],
                          ['c', 'x', 1], ['c', 'y', 2], ['c', 'z', 3],
                         ],
                         columns=['first', 'second', 'value1']
                         ).set_index(['first', 'second'])
      df2 = pd.DataFrame([['a', 10], ['b', 20]],
                         columns=['first', 'value2']).set_index(['first'])
      
      print(df1.join(df2, how='inner'))
                      value1  value2
      first second                  
      a     x       0.471780      10
            y       0.774908      10
            z       0.563634      10
      b     x      -0.353756      20
            y       0.368062      20
            z      -1.721840      20
      

      【讨论】:

        猜你喜欢
        • 2019-03-18
        • 2021-09-01
        • 2016-08-01
        • 2018-02-02
        • 2021-03-25
        • 2020-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多