我有一个如下数据框:
label val
a 0
b -1
b 0
b 1
a 1
b 1
我的目标是按标签列分组并获得两个聚合列。一个显示每组中行的数量(例如a:2,b:4),第二个显示每组中val = 1的比例。在熊猫中做到这一点的最佳方法是什么?
答案 0 :(得分:1)
尝试:
def portion(x): return (x.eq(1).sum())/len(x)
df.groupby('label').val.agg(['size', portion])
输出:
size portion
label
a 2 0.5
b 4 0.5
答案 1 :(得分:1)
找到满足条件的列的比例等效于取布尔序列的平均值。这使得它可以快速完成。由于s
和df
共享相同的索引,因此最好使用一个将另一个分组。
要获取一个列的多个聚合,请提供一个列表,该列表指定要执行的操作。
s = df.val.eq(1)
s.groupby(df.label).agg(['size', 'mean'])
# size mean
#label
#a 2 0.5
#b 4 0.5
使用“技巧”使组的数量增加时,比起使用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)