Pandas按用户分组高效计算当前Hits与上一分钟对应值的差值
高效计算用户每分钟Hits差值的矢量化方案
针对你遇到的大数据量下apply自定义函数速度过慢的问题,我们可以用pandas的矢量化分组操作来实现需求,完全不需要自定义函数,性能会提升很多。
实现思路
核心思路是先把时间聚合到分钟级别,提取每个用户每分钟的唯一Hits值,再计算分钟间的差值,最后把结果映射回原始数据的所有记录:
- 将
Datetime转换为datetime类型,并生成分钟级别的时间戳(用于分组)。 - 按
User和分钟时间分组,获取每组唯一的Hits值(因为同用户同分钟Hits完全一致)。 - 对每个用户的分钟级Hits序列计算差值(
diff()方法)。 - 将计算好的差值合并回原始DataFrame,让同分钟的所有记录共享同一个Delta值。
完整代码
import pandas as pd # 构造原始DataFrame d = {'User': ['A', 'A', 'A', 'A', 'B','A'], 'Datetime': ['2021-03-10 15:25:26', '2021-03-10 15:25:52', '2021-03-10 15:26:09', '2021-03-10 15:26:12', '2021-03-10 15:25:32', '2021-03-10 15:27:39'], 'Hits': [10,10,12,12,6,15]} df = pd.DataFrame(data=d) # 1. 转换时间格式并生成分钟级时间列 df['Datetime'] = pd.to_datetime(df['Datetime']) df['minute'] = df['Datetime'].dt.floor('min') # 2. 获取用户-分钟维度的唯一Hits记录,并计算差值 unique_hits = df.groupby(['User', 'minute'])['Hits'].first().reset_index() unique_hits['Delta'] = unique_hits.groupby('User')['Hits'].diff() # 3. 将差值合并回原始DataFrame df = df.merge(unique_hits[['User', 'minute', 'Delta']], on=['User', 'minute'], how='left') df = df.drop('minute', axis=1) # 移除临时列 # 查看结果 print(df)
输出结果
User Datetime Hits Delta 0 A 2021-03-10 15:25:26 10 <NA> 1 A 2021-03-10 15:25:52 10 <NA> 2 A 2021-03-10 15:26:09 12 2 3 A 2021-03-10 15:26:12 12 2 4 B 2021-03-10 15:25:32 6 <NA> 5 A 2021-03-10 15:27:39 15 3
为什么这个方案更快?
groupby和diff都是pandas底层实现的矢量化操作,基于C语言执行,比Python层面的自定义函数循环快几个数量级。- 我们只在用户-分钟的唯一记录上计算差值,避免了重复计算,进一步提升效率。
补充说明
因为同一用户同一分钟的Hits值完全相同,所以groupby时用first()、last()或者mean()都能得到相同的结果,你可以根据习惯选择。
内容的提问来源于stack exchange,提问作者Reno
相关产品推荐
相关产品推荐

