2015-04-02 51 views
4

我想计算每个多指标子水平的总和。然后,将其保存在数据框中。熊猫,计算每个MultiIndex子水平的总和

我目前的数据框的样子:

    values 
    first second 
    bar one  0.106521 
      two  1.964873 
    baz one  1.289683 
      two -0.696361 
    foo one -0.309505 
      two  2.890406 
    qux one -0.758369 
      two  1.302628 

和所需的结果是:

    values 
    first second 
    bar one  0.106521 
      two  1.964873 
      total 2.071394 
    baz one  1.289683 
      two -0.696361 
      total 0.593322 
    foo one -0.309505 
      two  2.890406 
      total 2.580901 
    qux one -0.758369 
      two  1.302628 
      total 0.544259 
    total one  0.328331 
      two  5.461546 
      total 5.789877 

目前我发现如下因素实现,它的工作原理。但我想知道是否有更好的选择。我需要尽可能快的解决方案,因为在某些情况下,当我的数据帧变大时,计算时间似乎需要很长时间。

In [1]: arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], 
    ...:   ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] 
    ...: 

In [2]: tuples = list(zip(*arrays)) 

In [3]: index = MultiIndex.from_tuples(tuples, names=['first', 'second']) 

In [4]: s = Series(randn(8), index=index) 

In [5]: d = {'values': s} 

In [6]: df = DataFrame(d) 

In [7]: for col in df.index.names: 
    .....:  df = df.unstack(col) 
    .....:  df[('values', 'total')] = df.sum(axis=1) 
    .....:  df = df.stack() 
    .....: 

回答

0

相当难看代码:

In [162]: 

print df 
       values 
first second   
bar one  0.370291 
     two  0.750565 
baz one  0.148405 
     two  0.919973 
foo one  0.121964 
     two  0.394017 
qux one  0.883136 
     two  0.871792 
In [163]: 

print pd.concat((df.reset_index(), 
       df.reset_index().groupby('first').aggregate('sum').reset_index())).\ 
         sort(['first','second']).\ 
         fillna('total').\ 
         set_index(['first','second']) 
       values 
first second   
bar one  0.370291 
     two  0.750565 
     total 1.120856 
baz one  0.148405 
     two  0.919973 
     total 1.068378 
foo one  0.121964 
     two  0.394017 
     total 0.515981 
qux one  0.883136 
     two  0.871792 
     total 1.754927 

基本上,由于所述附加行中,“总”,需要计算和插入原始数据帧,它是不会被一到原始与结果之间的一种关系,这种关系不是多对一的关系。所以,我认为你必须分别生成'总'数据框,并且使用原始数据框生成'全部'数据框。

+0

从我所看到的你设法计算总“第一”水平...我的需要涉及更多的水平,每个级别需要一个总数。我会测试你的解决方案,看看时间计算是否有任何改进。 – Iulian 2015-04-02 16:08:16