resample() 是一个基于时间的分组,然后对其每个组进行缩减方法。
然而,在比较groupby 中resamplevs的使用时,我注意到性能上存在巨大差异(有利于)pd.Grouperpd.Grouper
我有一个数据框,其中每行代表特定类型(认为是传感器)在某一天的值。它看起来像这样:
date type value
2018-01-01 1 12
2018-01-02 1 14
....
2018-01-01 2 12
....
Run Code Online (Sandbox Code Playgroud)
在该数据框上
df.set_index('DT').sort_index().groupby(['type']).resample('W').first()
Run Code Online (Sandbox Code Playgroud)
和
df.groupby(['type', pd.Grouper(key='DT', freq='W')]).first()
Run Code Online (Sandbox Code Playgroud)
做完全相同的事情。然而,在下面的示例数据集上,该resample方法比pd.Grouper方法慢约 30 倍(这与我在真实数据集上观察到的结果一致)。
这种性能下降从何而来?
# Creating the frame
date_range = pd.date_range(start=dt.datetime(2017,1,1), end=dt.datetime(2025,12,31), freq='W')
to_concat = []
for val in range(1,100):
frame_tmp = pd.DataFrame()
frame_tmp['DT'] = date_range
frame_tmp['type'] = val
frame_tmp['value'] = np.random.randint(1, 6, frame_tmp.shape[0])
to_concat.append(frame_tmp)
df = pd.concat(to_concat, ignore_index=True)
%%timeit
df.set_index('DT').sort_index().groupby(['type']).resample('W').first()
%%timeit
df.sort_values('DT').groupby(['type', pd.Grouper(key='DT', freq='W')]).first()
# Checking that they are indeed equals
res_groupby = df.sort_values('DT').groupby(['type', pd.Grouper(key='DT', freq='W')]).first()
res_resample = df.set_index('DT').sort_index().groupby(['type']).resample('W').first()
pd.DataFrame.equals(res_groupby, res_resample[['value']] )
Run Code Online (Sandbox Code Playgroud)
事实上它们并不等同,这个例子设计得很糟糕。相反,如果您使用freq='14D'in date_range,则框架将不等效。res_resample将会有NaN(每隔一周)的行,而res_groupby根本不会有它们。
事实上,在同等情况下重新采样似乎更慢,但它们不是同一件事,因此无法真正进行比较。