【问题标题】:mapping a multi-index to existing pandas dataframe columns using separate dataframe使用单独的数据框将多索引映射到现有的熊猫数据框列
【发布时间】:2018-09-29 06:37:32
【问题描述】:

我有一个以下格式的现有数据框(我们称之为df):

               A     B     C     D
0              1     2     1     4
1              3     0     2     2
2              1     5     3     1

列名是从具有以下形式的电子表格中提取的(我们称之为cat_df):

                      current category
broader category
X                     A
Y                     B
Y                     C
Z                     D

首先,我想添加一个更高级别的索引,使 df 看起来像这样:

               X     Y           Z
               A     B     C     D
0              1     2     1     4
1              3     0     2     2
2              1     5     3     1

最后,我想通过对子索引求和来将数据“汇总”到元索引中,以生成一个新的数据框,如下所示:

               X     Y     Z
0              1     3     4
1              3     2     2
2              1     8     1

使用来自this answerconcat 让我很接近,但似乎挑选每个子集是一个非常手动的过程。我的真实数据集具有更复杂的映射,因此我想在构建元索引时直接引用它。我认为一旦我确定了元索引,一个简单的groupby 应该可以让我得到总和,但我仍然停留在第一步。

【问题讨论】:

    标签: python pandas indexing


    【解决方案1】:
    d = dict(zip(cat_df['current category'], cat_df.index))
    
    cols = pd.MultiIndex.from_arrays([df.columns.map(d.get), df.columns])
    df.set_axis(cols, axis=1, inplace=False)
    
       X  Y     Z
       A  B  C  D
    0  1  2  1  4
    1  3  0  2  2
    2  1  5  3  1
    

    df_new = df.set_axis(cols, axis=1, inplace=False)
    df_new.groupby(axis=1, level=0).sum()
    
       X  Y  Z
    0  1  3  4
    1  3  2  2
    2  1  8  1
    

    【讨论】:

    • 这个对我来说效果很好,也是最容易理解的。但是,由于我使用的是旧版本的 Pandas 0.20.3,所以我必须进行一项修改。我用df.set_axis(1,cols) 替换了set_axis() 行(需要注意的是它会更改数据帧),因为版本0.22 中的语法发生了变化。
    【解决方案2】:

    IIUC,你可以这样做。

    df.columns = pd.MultiIndex.from_tuples(cat_df.reset_index()[['broader category','current category']].apply(tuple, axis=1).tolist())
    

    打印(df)

    输出:

       X  Y     Z
       A  B  C  D
    0  1  2  1  4
    1  3  0  2  2
    2  1  5  3  1
    

    总和水平:

    df.sum(level=0, axis=1)
    

    输出:

       X  Y  Z
    0  1  3  4
    1  3  2  2
    2  1  8  1
    

    【讨论】:

      【解决方案3】:

      您可以使用set_index 创建idx,然后分配给您的df

      idx=df1.set_index('category',append=True).index
      
      df.columns=idx
      
      df
      Out[1170]:
      current   X  Y     Z
      category  A  B  C  D
      0         1  2  1  4
      1         3  0  2  2
      2         1  5  3  1
      
      df.sum(axis=1,level=0)
      Out[1171]: 
      current  X  Y  Z
      0        1  3  4
      1        3  2  2
      2        1  8  1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        • 2020-12-02
        • 1970-01-01
        • 2019-06-30
        相关资源
        最近更新 更多