DataFrames 上的多索引和 Pandas 中的总和

Multiindex on DataFrames and sum in Pandas

我目前正在尝试使用 Pandas MultiIndex 属性。我正在尝试以一种聪明的方式根据其列对现有的 DataFrame 对象 df_original 进行分组,因此考虑了 MultiIndex。

print df_original =

       by_currency   by_portfolio    A  B  C
1        AUD          a              1  2  3
2        AUD          b              4  5  6
3        AUD          c              7  8  9
4        AUD          d              10 11 12
5        CHF          a              13 14 15 
6        CHF          b              16 17 18
7        CHF          c              19 20 21
8        CHF          d              22 23 24

现在,我想要的是一个 MultiIndex DataFrame 对象,其中 A, BC 以及 by_portfolio 作为索引。长得像

              CHF     AUD
A       a     13      1
        b     16      4   
        c     19      7
        d     22      10
B       a     14      2
        b     17      5
        c     20      8
        d     23      11
C       a     15      3
        b     18      6
        c     21      9
        d     24      12

我已经尝试将 df_original 中的所有列和搜索到的索引放入列表对象中,并从那里创建一个新的 DataFrame。这看起来有点麻烦,我不知道如何在之后添加实际值。

也许某种 groupby 更适合这个目的?问题是我需要能够将此数据添加到另一个类似的 DataFrame,因此我需要生成的 DataFrame 能够在以后添加到另一个 DataFrame。

谢谢

您可以使用 stackunstack 的组合:

In [50]: df.set_index(['by_currency', 'by_portfolio']).stack().unstack(0)
Out[50]:
by_currency     AUD  CHF
by_portfolio
a            A    1   13
             B    2   14
             C    3   15
b            A    4   16
             B    5   17
             C    6   18
c            A    7   19
             B    8   20
             C    9   21
d            A   10   22
             B   11   23
             C   12   24

为了得到您想要的结果,我们只需要交换索引的级别:

In [51]: df2 = df.set_index(['by_currency', 'by_portfolio']).stack().unstack(0)

In [52]: df2.columns.name = None

In [53]: df2.index = df2.index.swaplevel(0,1)

In [55]: df2 = df2.sort_index()

In [56]: df2
Out[56]:
                AUD  CHF
  by_portfolio
A a               1   13
  b               4   16
  c               7   19
  d              10   22
B a               2   14
  b               5   17
  c               8   20
  d              11   23
C a               3   15
  b               6   18
  c               9   21
  d              12   24