首页 > 解决方案 > Pandas Question 创建两个聚合,其中一个是有条件地创建的

问题描述

我有一个如下的数据框:

label  val
a        0
b       -1
b        0
b        1
a        1
b        1

我的目标是按标签列分组并获得两个聚合列。一个显示每组中的行数(例如a:2,b:4),第二个显示每组中val = 1的比例。在pandas中执行此操作的最佳方法是什么?

标签: pythonpandas

解决方案


找到满足条件的列的比例相当于取布尔系列的平均值。这允许它快速完成。由于sdf共享相同的索引,因此使用一个来分组另一个是完全可以的。

要为一列获取多个聚合,请提供一个指定您要执行的操作的列表。

s = df.val.eq(1)
s.groupby(df.label).agg(['size', 'mean'])

#       size  mean
#label            
#a         2   0.5
#b         4   0.5

当组的数量变大时,使用这样的“技巧”可能比使用 a 快得多,lambda因为许多基本groupby聚合都有性能非常好的 cythonized 版本。

# Create a sample df with 20,000 unique groups
df = pd.concat([df]*10000, ignore_index=True)
df['label'] = df.index//3

%%timeit
s = df.val.eq(1)
s.groupby(df.label).agg(['size', 'mean'])
#10.8 ms ± 300 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit 
def portion(x): return (x.eq(1).sum())/len(x)
df.groupby('label').val.agg(['size', portion])
#7.93 s ± 82.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

推荐阅读