Python中按周日至周六周维度聚合count值的高效实现
高效实现按ID和周(周日至周六)汇总Count值的方法
问题描述
现有如下DataFrame:
| id | date | count |
|---|---|---|
| 1 | 8/31/22 | 1 |
| 1 | 9/1/22 | 2 |
| 1 | 9/2/22 | 8 |
| 1 | 9/3/22 | 0 |
| 1 | 9/4/22 | 3 |
| 1 | 9/5/22 | 5 |
| 1 | 9/6/22 | 1 |
| 1 | 9/7/22 | 6 |
| 1 | 9/8/22 | 5 |
| 1 | 9/9/22 | 7 |
| 1 | 9/10/22 | 1 |
| 2 | 8/31/22 | 0 |
| 2 | 9/1/22 | 2 |
| 2 | 9/2/22 | 0 |
| 2 | 9/3/22 | 5 |
| 2 | 9/4/22 | 1 |
| 2 | 9/5/22 | 6 |
| 2 | 9/6/22 | 1 |
| 2 | 9/7/22 | 1 |
| 2 | 9/8/22 | 2 |
| 2 | 9/9/22 | 2 |
| 2 | 9/10/22 | 0 |
需求:按id分组,将每周(周日开始,周六结束)的count总和汇总到对应周六的日期上,所有id统计时间范围固定,期望输出:
| id | date | count |
|---|---|---|
| 1 | 9/3/22 | 11 |
| 1 | 9/10/22 | 28 |
| 2 | 9/3/22 | 7 |
| 2 | 9/10/22 | 13 |
原代码通过循环逐ID处理、频繁拼接小DataFrame的方式实现,但大数据量下效率极低,需要更高效的实现方案。
高效解决方案
利用Pandas内置的向量化分组聚合功能,彻底避免循环和冗余操作,代码如下:
import pandas as pd # 确保date列是datetime类型(如果原始数据未转换) df['date'] = pd.to_datetime(df['date']) # 按id+周(周六为周结束日)分组求和 week_summary = df.groupby( ['id', pd.Grouper(key='date', freq='W-SAT')] )['count'].sum().reset_index() # 过滤空值并得到最终结果 df_final = week_summary.dropna(subset=['date'])
代码说明
- 日期类型转换:先将
date列转为datetime格式,这是时间维度分组的基础。 - 周分组规则:
pd.Grouper(freq='W-SAT')指定每周以周六为结束日,自动将每个id下的日期按「周日-周六」的周期划分。 - 聚合求和:直接对每个分组的
count求和,reset_index()将分组索引转回普通列,得到结构化结果。 - 结果清理:用
dropna过滤可能存在的无数据周,确保输出和预期一致。
原代码低效原因
- 循环逐ID处理:Pandas的核心优势是向量化操作,循环会完全浪费其性能优化,数据量越大耗时越明显。
- 频繁拼接DataFrame:
pd.concat每次都会创建新对象,多次拼接会产生大量内存拷贝和开销。 - 手动定位周六索引:遍历数据查找周六位置的逻辑冗余,且额外增加了计算成本。
内容的提问来源于stack exchange,提问作者Amir
相关产品推荐
相关产品推荐

