一种更好的方法来聚合数据并保持表结构和列名与Pandas

时间:2016-01-06 03:49:47

标签: python pandas

假设我有一个类似于以下

的数据集
df = pd.DataFrame({'x1':['a','a','b','b'], 'x2':[True, True, True, False], 'x3':[1,1,1,1]})
df
  x1     x2  x3
0  a   True   1
1  a   True   1
2  b   True   1
3  b  False   1

我经常想要执行groupby-aggregate操作,其中我按多列分组并将多个函数应用于一列。此外,我通常不需要多索引的多级表。为了实现这一点,它带了我三行代码似乎过分了。

例如

bg = df.groupby(['x1', 'x2']).agg({'x3': {'my_sum':np.sum, 'my_mean':np.mean}})
bg.columns = bg.columns.droplevel(0)
bg.reset_index()

有更好的方法吗?不要抱怨,但我来自R / data.table背景,这样的事情很好,像

df[, list(my_sum=sum(x3), my_mean=mean(x3)), by=list(x1, x2)]

2 个答案:

答案 0 :(得分:5)

这个怎么样:

In [81]: bg = df.groupby(['x1', 'x2'], as_index=False)['x3'].agg({'my_sum':np.sum, 'my_mean':np.mean})

In [82]: print bg
  x1     x2  my_sum  my_mean
0  a   True       2        1
1  b  False       1        1
2  b   True       1        1

答案 1 :(得分:2)

你可以使用@ Happy01答案,而不是as_index=False,你可以添加reset_index到最后:

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

基准测试,对于reset_index,效果更快:

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

你可以用你的解决方案做同样的事情但只有一行。转置您的数据框,然后reset_index放弃x3列或0级,然后转置回来再次执行reset_index以获得所需的输出:

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

但效果较慢:

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