You can use @ Happy01's answer, but instead of as_index=False you can add reset_index to the end:
In [1331]: df.groupby(['x1', 'x2'])['x3'].agg( {'my_sum':np.sum, 'my_mean':np.mean}).reset_index() Out[1331]: x1 x2 my_mean my_sum 0 a True 1 2 1 b False 1 1 2 b True 1 1
Benchmarking , for reset_index it works faster:
In [1333]: %timeit df.groupby(['x1', 'x2'], as_index=False)['x3'].agg({'my_sum':np.sum, 'my_mean':np.mean}) 100 loops, best of 3: 3.18 ms per loop In [1334]: %timeit df.groupby(['x1', 'x2'])['x3'].agg( {'my_sum':np.sum, 'my_mean':np.mean}).reset_index() 100 loops, best of 3: 2.82 ms per loop
You can do the same as your solution, but with one line. Transport your framework, then reset_index to drop the x3 column or level 0, then move back and reset_index again to achieve the desired result:
In [1374]: df.groupby(['x1', 'x2']).agg({'x3': {'my_sum':np.sum, 'my_mean':np.mean}}).T.reset_index(level=0, drop=True).T.reset_index() Out[1374]: x1 x2 my_mean my_sum 0 a True 1 2 1 b False 1 1 2 b True 1 1
But it works slower:
In [1375]: %timeit df.groupby(['x1', 'x2']).agg({'x3': {'my_sum':np.sum, 'my_mean':np.mean}}).T.reset_index(level=0, drop=True).T.reset_index() 100 loops, best of 3: 5.13 ms per loop
source share