基于自定义财季计算学生前两季度营收并重塑Pandas DataFrame
自定义财历季度的学生营收统计解决方案
原始数据与需求
初始DataFrame
import pandas as pd df = pd.DataFrame( {'stud_id' : [101, 101, 101, 101, 101, 102, 102, 102], 'sub_code' : ['CSE01', 'CSE01', 'CSE01', 'CSE01', 'CSE02', 'CSE02', 'CSE02', 'CSE02'], 'ques_date' : ['10/11/2022', '06/06/2022','09/04/2022', '27/03/2022', '13/05/2010', '10/11/2021','11/1/2022', '27/02/2022'], 'revenue' : [77, 86, 55, 90, 65, 90, 80, 67]} ) df['ques_date'] = pd.to_datetime(df['ques_date'], dayfirst=True)
需求说明
- a) 自定义财历季度:10-12月为Q1,1-3月为Q2,4-6月为Q3,7-9月为Q4
- b) 按
stud_id分组 - c) 以
20/12/2022(对应2023Q1)为基准,计算每个学生前两个季度(2022Q4、2022Q3)的营收总和
已尝试代码
df['custom_qtr'] = pd.to_datetime(df['ques_date'], dayfirst=True).dt.to_period('Q-SEP') date_1 = pd.to_datetime('20-12-2022') df['date_based_qtr'] = date_1.to_period('Q-SEP') pat = '(Q(\d+))' df['custom_qtr_number'] = df['custom_qtr'].astype(str).str.extract(pat, expand=False)[1] df['date_qtr_number'] = df['date_based_qtr'].astype(str).str.extract(pat, expand=False)[1]
完整解决方案
你的思路方向是对的,Q-SEP确实匹配咱们需要的自定义财历(财年结束于9月,10-12月为下一年Q1),接下来只需完成筛选、聚合和重塑即可:
步骤1:生成正确的自定义季度
因为已经把ques_date转成datetime格式,直接生成季度周期即可:
# 生成自定义财历季度,Q-SEP表示财年结束于9月,完全匹配需求的季度划分 df['custom_qtr'] = df['ques_date'].dt.to_period('Q-SEP')
步骤2:确定目标季度
基准日期20/12/2022对应的季度是2023Q1,往前推两个季度就是2022Q4和2022Q3:
base_qtr = pd.to_datetime('20-12-2022', dayfirst=True).to_period('Q-SEP') # 计算前两个目标季度 target_qtrs = [base_qtr - 1, base_qtr - 2]
步骤3:筛选目标季度的数据
只保留属于2022Q3和2022Q4的记录:
filtered_df = df[df['custom_qtr'].isin(target_qtrs)]
步骤4:分组聚合并重塑为宽表
按学生和季度分组求和,再转成宽表让每个学生一行、季度作为列:
# 分组求和 result = filtered_df.groupby(['stud_id', 'custom_qtr'])['revenue'].sum().unstack() # 重命名列,让显示更清晰(可选操作) result.columns = [f'{col}营收总和' for col in result.columns] # 重置索引,把stud_id从索引变回普通列(可选操作) result = result.reset_index()
最终结果
运行后得到的result就是目标输出:
| stud_id | 2022Q3营收总和 | 2022Q4营收总和 |
|---|---|---|
| 101 | 141 | 77 |
| 102 | NaN | NaN |
(注:学生102的记录里没有2022Q3/Q4的数据,所以显示NaN,若需要填充0可以在代码末尾加.fillna(0))
完整代码整合
import pandas as pd # 初始化数据 df = pd.DataFrame( {'stud_id' : [101, 101, 101, 101, 101, 102, 102, 102], 'sub_code' : ['CSE01', 'CSE01', 'CSE01', 'CSE01', 'CSE02', 'CSE02', 'CSE02', 'CSE02'], 'ques_date' : ['10/11/2022', '06/06/2022','09/04/2022', '27/03/2022', '13/05/2010', '10/11/2021','11/1/2022', '27/02/2022'], 'revenue' : [77, 86, 55, 90, 65, 90, 80, 67]} ) df['ques_date'] = pd.to_datetime(df['ques_date'], dayfirst=True) # 生成自定义季度 df['custom_qtr'] = df['ques_date'].dt.to_period('Q-SEP') # 确定目标季度 base_qtr = pd.to_datetime('20-12-2022', dayfirst=True).to_period('Q-SEP') target_qtrs = [base_qtr - 1, base_qtr - 2] # 筛选+聚合+重塑 result = df[df['custom_qtr'].isin(target_qtrs)] \ .groupby(['stud_id', 'custom_qtr'])['revenue'].sum() \ .unstack() \ .fillna(0) # 可选:把NaN替换为0 result.columns = [f'{col}营收总和' for col in result.columns] result = result.reset_index() print(result)
内容的提问来源于stack exchange,提问作者The Great
相关产品推荐
相关产品推荐

