You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas计算并透视获取前两个自定义财年的营收数据

问题描述

给定如下DataFrame:

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'])

需完成以下操作:

  • a) 按自定义财历计算财年:10-12月为Q1,1-3月为Q2,4-6月为Q3,7-9月为Q4
  • b) 按stud_id分组
  • c) 计算截止日期20/12/2022前两个自定义财年的营收总和(截止日期处于FY-2023,需统计FY-2022和FY-2021的营收)

尝试了以下代码,但输出列不符合预期:

df['custom_qtr'] = pd.to_datetime(df['ques_date'], dayfirst=True).dt.to_period('Q-SEP')
date_1 = pd.to_datetime('20-12-2022') # CUT-OFF DATE
df['custom_year'] = df['custom_qtr'].astype(str).str.extract('(?P<year>\d+)')
df['date_based_qtr']  = date_1.to_period('Q-SEP')
df['custom_date_year'] = df['date_based_qtr'].astype(str).str.extract('(?P<year>\d+)')
df['custom_year'] = df['custom_year'].astype(int)
df['custom_date_year'] = df['custom_date_year'].astype(int)
df['diff'] = df['custom_date_year'].sub(df['custom_year'])
df = df[df['diff'].isin([1,2])]
out_df = df.pivot_table("revenue", index=['stud_id'],columns=['custom_year'],aggfunc=['sum']).add_prefix('rev_').reset_index().droplevel(0,axis=1)

当前输出存在列层级混乱、数据统计偏差问题,期望输出如下:

stud_idFY_2021FY_2022
1010308
10290147
解决方案

核心思路

你的自定义财历本质是财年以9月为结束节点(10月开启新财年),可以利用pandas的周期类型直接匹配该规则,再精准筛选目标财年数据后分组求和。

修正后的代码

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)

# 计算自定义财年:Q-SEP表示财年结束于9月,提取年份即为财年编号
df['fy'] = df['ques_date'].dt.to_period('Q-SEP').dt.year

# 确定截止日期对应的财年
cutoff_date = pd.to_datetime('20/12/2022', dayfirst=True)
cutoff_fy = cutoff_date.to_period('Q-SEP').year

# 筛选目标财年:截止财年的前两个财年
target_fys = [cutoff_fy - 2, cutoff_fy - 1]
filtered_df = df[df['fy'].isin(target_fys)]

# 分组求和并转换为宽表,缺失财年填充0
result = filtered_df.groupby(['stud_id', 'fy'])['revenue'].sum().unstack(fill_value=0)

# 重命名列并固定列顺序
result = result.rename(columns={fy: f'FY_{fy}' for fy in target_fys}).reset_index()
result = result[['stud_id', 'FY_2021', 'FY_2022']]

print(result)

输出结果

stud_id  FY_2021  FY_2022
0      101        0      308
1      102       90      147

代码说明

  1. 财年计算:dt.to_period('Q-SEP')直接匹配"10月启新财年"的规则,提取的年份就是财年编号(例如2022年10月属于FY2023,2022年9月属于FY2022)
  2. 筛选逻辑:截止日期2022-12-20属于FY2023,因此取前两个财年FY2021、FY2022的数据
  3. 分组重塑:用groupby+unstack生成宽表,fill_value=0确保无数据的财年显示0值
  4. 列名优化:重命名列使其更直观,同时固定列顺序匹配期望输出

内容的提问来源于stack exchange,提问作者The Great

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:00:54