Python Pandas:如何使用返回pd.Series的函数对聚合进行分组

时间:2019-08-28 01:10:23

标签: python pandas dataframe

我有一个多索引数据框,我想在该数据框上汇总一些索引。如果聚合函数返回浮点数,则说明一切正常。但是我找不到如何使用返回值更复杂的函数(例如pd.Series)。使用返回pd.Series的函数会给我以下错误:Exception: Must produce aggregated value错误。

这是一个示例数据框:

df = pd.DataFrame({
    'A': {
        (1, 0): 85, (1, 1): 75,
        (2, 0): 12, (2, 1): 15,
        (3, 0): 2,  (3, 1): 26,
    },
    'B': {
        (1, 0): 86, (1, 1): 76,
        (2, 0): 13, (2, 1): 17,
        (3, 0): 19, (3, 1): 18,
    }
}).stack()
df.index.rename(['idx', 'bar', 'label'], inplace=True)

df的内容是:

idx  bar  label
1    0    A        85
          B        86
     1    A        75
          B        76
2    0    A        12
          B        13
     1    A        15
          B        17
3    0    A         2
          B        19
     1    A        26
          B        18
dtype: int64

让我们定义一个简单的聚合器,该聚合器返回pd.Series:

def my_func(subframe):
  subframe = subframe.unstack('label')
  mean_A_plus_B = np.mean(subframe['B'] + subframe['A'])
  mean_A_minus_B = np.mean(subframe['B'] - subframe['A'])
  return pd.Series([mean_A_plus_B, mean_A_minus_B], index=['A+B', 'A-B'])
  # return mean_A_plus_B  ## <- this one works.

像以下情况一样应用聚合器:

df.groupby('idx').agg(my_func)
.
.
.
py/pandas/core/groupby/generic.py in _aggregate_named(self, func, *args, **kwargs)
    907             output = func(group, *args, **kwargs)
    908             if isinstance(output, (Series, Index, np.ndarray)):
--> 909                 raise Exception('Must produce aggregated value')
    910             result[name] = self._try_cast(output, group)

Exception: Must produce aggregated value

我希望得到的是:

       A+B    A-B
idx
1    161.0    1.0
2     28.5    1.5
3     32.5    4.5
dtype: float64

正确的做法是什么?

1 个答案:

答案 0 :(得分:3)

只需将.agg()替换为.apply()

df.groupby('idx').apply(my_func).unstack(level=-1)

输出:

       A+B  A-B
idx            
1    161.0  1.0
2     28.5  1.5
3     32.5  4.5