如何按ID分组计算连续两周的金额总和(基于周维度)
计算两周滚动周金额总和(当前周+上一周)
需求说明
给定如下输入DataFrame:
| ID | Date | Amount |
|---|---|---|
| A | 2021-08-03 | 100 |
| A | 2021-08-04 | 100 |
| A | 2021-08-06 | 20 |
| A | 2021-08-07 | 100 |
| A | 2021-08-09 | 300 |
| A | 2021-08-11 | 100 |
| A | 2021-08-12 | 100 |
| A | 2021-08-13 | 10 |
| A | 2021-08-23 | 10 |
| A | 2021-08-24 | 10 |
| A | 2021-08-26 | 10 |
| A | 2021-08-28 | 10 |
需要新增TwoWeekSum列,计算规则为:当前周金额总和 + 上一周金额总和,同一周内的所有记录共享该周的两周总和值,最终输出如下:
| ID | Date | Amount | TwoWeekSum |
|---|---|---|---|
| A | 2021-08-03 | 100 | 320 |
| A | 2021-08-04 | 100 | 320 |
| A | 2021-08-06 | 20 | 320 |
| A | 2021-08-07 | 100 | 320 |
| A | 2021-08-09 | 300 | 830 |
| A | 2021-08-11 | 100 | 830 |
| A | 2021-08-12 | 100 | 830 |
| A | 2021-08-13 | 10 | 830 |
| A | 2021-08-23 | 10 | 40 |
| A | 2021-08-24 | 10 | 40 |
| A | 2021-08-26 | 10 | 40 |
| A | 2021-08-28 | 10 | 40 |
实现代码(Pandas)
import pandas as pd # 1. 构造输入数据(实际使用时可替换为读取你的数据源) data = { 'ID': ['A']*12, 'Date': ['2021-08-03', '2021-08-04', '2021-08-06', '2021-08-07', '2021-08-09', '2021-08-11', '2021-08-12', '2021-08-13', '2021-08-23', '2021-08-24', '2021-08-26', '2021-08-28'], 'Amount': [100, 100, 20, 100, 300, 100, 100, 10, 10, 10, 10, 10] } df = pd.DataFrame(data) # 2. 转换日期格式,提取年份和ISO周数(避免跨年周冲突) df['Date'] = pd.to_datetime(df['Date']) df['Year'] = df['Date'].dt.isocalendar().year df['Week'] = df['Date'].dt.isocalendar().week # 3. 按ID、年份、周分组,计算每周金额总和 weekly_total = df.groupby(['ID', 'Year', 'Week'])['Amount'].sum().reset_index() weekly_total.rename(columns={'Amount': 'WeeklySum'}, inplace=True) # 4. 计算两周滚动总和:当前周 + 上一周总和,无数据的上一周补0 weekly_total['TwoWeekSum'] = weekly_total.groupby('ID')['WeeklySum'].transform( lambda x: x + x.shift(1).fillna(0) ) # 5. 将两周总和合并回原始数据,匹配对应ID、年份、周 result = df.merge(weekly_total[['ID', 'Year', 'Week', 'TwoWeekSum']], on=['ID', 'Year', 'Week'], how='left') # 6. 整理输出列顺序,去掉中间辅助列 result = result[['ID', 'Date', 'Amount', 'TwoWeekSum']] print(result)
代码说明
- 日期处理:使用
isocalendar()提取年份和周数,确保跨年场景下的周数准确性。 - 周级汇总:先按ID、年、周分组计算单周总金额,为后续两周求和做基础。
- 滚动求和:通过
groupby('ID')限定在同一用户内计算,shift(1)获取上一周数据,fillna(0)处理无前置周的情况(如第一周、间隔周)。 - 合并数据:将周级别的两周总和关联到原始每条记录,保证同一周的所有记录拥有相同的
TwoWeekSum值。
内容的提问来源于stack exchange,提问作者Rahi007
相关产品推荐
相关产品推荐

