将行附加到Pandas groupby对象

时间:2015-03-16 16:47:15

标签: python pandas

我正在试图找出将这些方法重新插入多索引pandas数据帧的最佳方法。

假设我有一个这样的数据框:

      metric 1     metric 2    
             R   P        R   P
foo a        0   1        2   3
    b        4   5        6   7
bar a        8   9       10  11
    b       12  13       14  15

我想得到以下结果:

      metric 1     metric 2    
             R   P        R   P
foo a        0   1        2   3
    b        4   5        6   7
  AVG        2   3        4   5
bar a        8   9       10  11
    b       12  13       14  15
  AVG       10  11       12  13

请注意,我知道我可以df.mean(level=0)来获得0级组意味着作为单独的数据帧。这不是我想要的 - 我想插入组意味着作为行返回到组中。

我能够得到我想要的结果,但我觉得我这样做错了/可能有一个我错过的衬垫已经没有昂贵的python迭代。这是我的示例代码:

import numpy as np
import pandas as pd

data = np.arange(16).reshape(4,4)
row_index = [("foo", "a"), ("foo", "b"), ("bar", "a"), ("bar", "b")]
col_index = [("metric 1", "R"), ("metric 1", "P"), ("metric 2", "R"),  
    ("metric 2", "P")]
col_multiindex = pd.MultiIndex.from_tuples(col_index)
df = pd.DataFrame(data, index=pd.MultiIndex.from_tuples(row_index),
    columns=col_multiindex)

new_row_index = []
data = []
for name, group in df.groupby(level=0):
    for index_tuple, row in group.iterrows():
        new_row_index.append(index_tuple)
        data.append(row.tolist())
    new_row_index.append((name, "AVG"))
    data.append(group.mean().tolist())

print pd.DataFrame(data, 
    index=pd.MultiIndex.from_tuples(new_row_index), 
    columns=col_multiindex)

结果是:

        metric 1     metric 2    
               R   P        R   P
bar a          8   9       10  11
    b         12  13       14  15
    AVG       10  11       12  13
foo a          0   1        2   3
    b          4   5        6   7
    AVG        2   3        4   5

由于某种原因翻转了组的顺序,但或多或​​少是我想要的。

1 个答案:

答案 0 :(得分:0)

您需要做的主要事情是将您的资源附加到主数据集。在执行此操作之前,您需要的主要技巧是使索引符合(使用reset_index()set_index(),以便在添加它们之后,它们或多或少会排成一行并准备基于相同的排序密钥。

In [35]: df2 = df.groupby(level=0).mean()

In [36]: df2['index2'] = 'AVG'

In [37]: df2 = df2.reset_index().set_index(['index','index2']).append(df).sort()

In [38]: df2
Out[38]: 
             metric 1     metric 2    
                    R   P        R   P
index index2                          
bar   AVG          10  11       12  13
      a             8   9       10  11
      b            12  13       14  15
foo   AVG           2   3        4   5
      a             0   1        2   3
      b             4   5        6   7

就排序行而言,最好的方法可能只是设置名称,以便排序将它们放在正确的位置(例如A,B,avg)。或者对于少量行,您可以使用花哨的索引:

In [39]: df2.ix[[4,5,3,1,2,0]]
Out[39]: 
             metric 1     metric 2    
                    R   P        R   P
index index2                          
foo   a             0   1        2   3
      b             4   5        6   7
      AVG           2   3        4   5
bar   a             8   9       10  11
      b            12  13       14  15
      AVG          10  11       12  13