Pandas v1.1.0:Groupby滚动计数慢于滚动平均值&总和

我正在运行一个groupby滚动计数、总和和;使用Pandas v1.1.0的平均值,我注意到滚动计数比滚动平均值慢得多&总和这似乎违反直觉,因为我们可以从平均值和总和中得出计数,从而节省时间。这是一个错误还是我遗漏了什么?谢谢你的建议

将熊猫作为pd导入
#生成样本df
df=pd.DataFrame({'column1':范围(600),'group':5*['l'+str(i)表示范围(120)])
#按组排序,方便/高效地将新列连接到df
df=df.sort_值('group',kind='mergesort')。重置_索引(drop=True)
#按滚动计数、总和和平均数分组的计时
%timeit df['mean']=df.groupby('group').rolling(3,min_periods=1)['column1'].mean().values
%timeit df['sum']=df.groupby('group').rolling(3,min_periods=1)['column1'].sum().values
%timeit df['count']=df.groupby('group')。滚动(3,最小周期=1)['column1'].count()。值
###输出
每个回路6.14 ms±812µs(7次运行的平均值±标准偏差,每个100个回路)
每个回路5.61 ms±179µs(7次运行的平均值±标准偏差,每个100个回路)
每个回路76.1 ms±4.78 ms(7次运行的平均值±标准偏差,每个10个回路)
###用于说明的df输出
打印(测向头(10))
第1列组平均和计数
0 l0 0.0 0.0 1.0
1120L060.01220.02.0
2 240 l0 120.0 360.0 3.0
3360L0240.0720.03.0
4480 l0 360.0 1080.0 3.0
5 1 l1 1.0 1.0 1.0
6121L1 61.0122.0
7241 l1 121.0363.03.0
8361 l1 241.0 723.0 3.0
9481 l1 361.0 1083.0 3.0

你真的是指count(非NaN值的数量)?不能仅从summean推断出来

我怀疑您要查找的是size操作符(只是组的长度,而不管是否有NAN)。虽然size存在于常规的groupby中,但在RollingGroupBy中似乎不存在它(至少从1.1.4开始)。可以使用以下公式计算轧制组的尺寸:

干燥:
rgb=df.groupby(’group’)。滚动(3,最小周期=1)[‘column1’]
#尺寸为:
rgb.apply(len)
#或
rgb.apply(lambda g:g.shape[0])

当然,这两种方法的速度都不尽可能快,因为每个组都需要调用函数,而不是全部矢量化,并在滚动窗口索引startend之外工作。在我的系统上,以上任一项都比rgb.sum()rgb.mean()慢2倍

思考如何实现size:这是显而易见的(每个窗口只需end-start

现在,如果一个真的想加快计数(非NaN值的计数):可以建立一个;累积计数“;首先:

cumcnt=(1-df['column1'].isnull()).cumsum()

(这非常快,大约比我的系统上的rgb.mean()快200倍)

然后滚动函数可以简单地执行cumcnt[end]-cumcnt[start]

我对RollingGroupBy的内部结构(以及它们对各种mixins的使用)了解不够,无法评估其可行性,但至少在功能上它看起来相当简单

更新:

这些提交似乎已经解决了这个问题。这既快又简单——熊猫的内部结构和他们瑞士军刀上已有的所有工具给我留下了深刻的印象

发表评论