从 Pandas 版本 0.22 开始,还存在apply
:的替代方案pipe
,它可以比使用快得多apply
(您也可以检查这个问题以了解这两个功能之间的更多差异)。
对于您的示例:
df = pd.DataFrame({"my_label": ['A','B','A','C','D','D','E']})
my_label
0 A
1 B
2 A
3 C
4 D
5 D
6 E
apply
版本_
df.groupby('my_label').apply(lambda grp: grp.count() / df.shape[0])
给
my_label
my_label
A 0.285714
B 0.142857
C 0.142857
D 0.285714
E 0.142857
和pipe
版本
df.groupby('my_label').pipe(lambda grp: grp.size() / grp.size().sum())
产量
my_label
A 0.285714
B 0.142857
C 0.142857
D 0.285714
E 0.142857
所以值是相同的,但是,时间差异很大(至少对于这个小数据帧):
%timeit df.groupby('my_label').apply(lambda grp: grp.count() / df.shape[0])
100 loops, best of 3: 5.52 ms per loop
和
%timeit df.groupby('my_label').pipe(lambda grp: grp.size() / grp.size().sum())
1000 loops, best of 3: 843 µs per loop
将它包装成一个函数也很简单:
def get_perc(grp_obj):
gr_size = grp_obj.size()
return gr_size / gr_size.sum()
现在你可以打电话
df.groupby('my_label').pipe(get_perc)
屈服
my_label
A 0.285714
B 0.142857
C 0.142857
D 0.285714
E 0.142857
但是,对于这种特殊情况,您甚至不需要 a groupby
,但您可以value_counts
像这样使用:
df['my_label'].value_counts(sort=False) / df.shape[0]
屈服
A 0.285714
C 0.142857
B 0.142857
E 0.142857
D 0.285714
Name: my_label, dtype: float64
对于这个小数据框,它非常快
%timeit df['my_label'].value_counts(sort=False) / df.shape[0]
1000 loops, best of 3: 770 µs per loop
正如@anmol 所指出的,最后一条语句也可以简化为
df['my_label'].value_counts(sort=False, normalize=True)