按自定义财季日期分组汇总DataFrame数值的技术咨询
自定义非日历年财季的数值求和方案
核心思路
利用你定义的财季起始日期生成有序区间,通过pd.cut将DataFrame的日期映射到对应财季,再分组求和即可。
具体实现步骤
1. 整理财季起始日期为有序映射
把你分散定义的财季起始日期转换成带名称的有序列表,补充初始财季(F1Q17)以覆盖所有数据:
import pandas as pd from datetime import date # 原样本数据 begin_date = '2017-01-01' values = [*range(2100)] df = pd.DataFrame({'values': values, 'dates': pd.date_range(begin_date, periods=len(values))}) # 整理财季:(财季名称, 起始日期),严格按时间顺序排列 fiscal_q_starts = [ ("F1Q17", pd.to_datetime(begin_date)), ("F2Q17", pd.to_datetime(date(2017, 4, 1))), ("F3Q17", pd.to_datetime(date(2017, 7, 1))), ("F4Q17", pd.to_datetime(date(2017, 9, 30))), ("F1Q18", pd.to_datetime(date(2017, 12, 30))), ("F2Q18", pd.to_datetime(date(2018, 3, 31))), ("F3Q18", pd.to_datetime(date(2018, 6, 30))), ("F4Q18", pd.to_datetime(date(2018, 9, 29))), ("F1Q19", pd.to_datetime(date(2018, 12, 29))), ("F2Q19", pd.to_datetime(date(2019, 3, 30))), ("F3Q19", pd.to_datetime(date(2019, 6, 29))), ("F4Q19", pd.to_datetime(date(2019, 9, 28))), ("F1Q20", pd.to_datetime(date(2019, 12, 28))), ("F2Q20", pd.to_datetime(date(2020, 3, 28))), ("F3Q20", pd.to_datetime(date(2020, 6, 27))), ("F4Q20", pd.to_datetime(date(2020, 9, 26))), ("F1Q21", pd.to_datetime(date(2020, 12, 26))), ("F2Q21", pd.to_datetime(date(2021, 3, 27))), ("F3Q21", pd.to_datetime(date(2021, 6, 26))), ("F4Q21", pd.to_datetime(date(2021, 9, 25))), ("F1Q22", pd.to_datetime(date(2021, 12, 25))), ("F2Q22", pd.to_datetime(date(2022, 3, 26))), ("F3Q22", pd.to_datetime(date(2022, 6, 25))), ("F4Q22", pd.to_datetime(date(2022, 9, 25))), ] # 生成区间边界:所有财季起始日期 + 数据最后日期(作为最后一个区间的结束) q_bins = [q[1] for q in fiscal_q_starts] + [df['dates'].max()] # 财季名称作为区间标签 q_labels = [q[0] for q in fiscal_q_starts]
2. 映射日期到财季并计算求和
使用pd.cut将每个日期分配到对应财季区间,再按财季分组求和:
# 给DataFrame添加财季列,左闭右开区间,include_lowest确保起始日期被包含 df['fiscal_quarter'] = pd.cut(df['dates'], bins=q_bins, labels=q_labels, include_lowest=True) # 按财季分组求和,得到结果 quarterly_sum = df.groupby('fiscal_quarter')['values'].sum().reset_index() # 打印结果 print(quarterly_sum)
关键细节
- 区间逻辑:
pd.cut默认左闭右开,刚好匹配财季起始日期的定义(比如F2Q17包含2017-04-01及之后,直到F3Q17起始日之前) - 类型统一:将
datetime.date转换为pd.Timestamp,避免和DataFrame中dates列的类型冲突 - 全数据覆盖:补充初始财季和最后区间的结束日期,确保没有数据被遗漏
内容的提问来源于stack exchange,提问作者majorarc6
相关产品推荐
相关产品推荐

