代码之家  ›  专栏  ›  技术社区  ›  Ben

用Pandas聚合数据并保留表结构和列名的更好方法

  •  5
  • Ben  · 技术社区  · 8 年前

    假设我有一个如下的数据集

    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
    

    我经常想执行逐组聚合操作,其中我按多个列进行分组,并将多个函数应用于一列。此外,我通常不想要多索引、多层次的表。为了实现这一点,我需要三行代码,这似乎有些过分。

    例如

    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/数据。桌子背景,像这样的东西是一个不错的一行

    df[, list(my_sum=sum(x3), my_mean=mean(x3)), by=list(x1, x2)]
    
    2 回复  |  直到 8 年前
        1
  •  5
  •   Happy001    8 年前

    这个怎么样:

    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
    
        2
  •  2
  •   Anton Protopopov    8 年前

    你可以使用@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
    

    标杆管理 对于 重置索引 它工作得更快:

    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
    

    你可以做与你的解决方案相同的事情,但只有一行。转换数据帧,然后执行 重置索引 放下你的 x3 列或级别0,然后转回并执行 重置索引 再次实现您想要的输出:

    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