如何在Pandas中获取各项目的上年同季度值及月度环比值
解决方案
要实现每个项目上年同期季度值的匹配,核心是让同一项目的同季度数据对齐,而非单纯按行偏移。直接用shift(1)只会取上一行数据(即上一季度),我们需要先拆分季度标识,提取年份和季度编号,再按项目+季度编号分组后偏移,就能精准匹配上年同期。
步骤1:拆分季度列,提取年份与季度编号
先从quarter列中分离出年份和季度编号,方便后续分组匹配:
import pandas as pd # 原数据 df = pd.DataFrame({'item':['A','A','A','A','A','A','B','B','B','B','B','B','C','C','C','C','C','C'], 'quarter':['FY20_Q1','FY20_Q2','FY20_Q3','FY20_Q4','FY21_Q1','FY21_Q2', 'FY20_Q1','FY20_Q2','FY20_Q3','FY20_Q4','FY21_Q1','FY21_Q2', 'FY20_Q1','FY20_Q2','FY20_Q3','FY20_Q4','FY21_Q1','FY21_Q2'], 'value':[100,150,120,135,128,160,230,210,240,220,250,230,125,230,162,111,134,135]}) # 拆分年份和季度编号 df[['year', 'qtr']] = df['quarter'].str.extract(r'FY(\d+)_Q(\d+)').astype(int) # 转换为完整年份(FY20 → 2020) df['year'] = df['year'] + 2000
步骤2:按项目+季度编号分组,偏移匹配上年同期
按item和qtr分组后,对value列执行shift(1),此时同一项目同一季度的上一年数据会被对应到当前行:
# 计算上年同期值 df['value_prev'] = df.sort_values(by=['item', 'year', 'qtr']).groupby(['item', 'qtr'])['value'].shift(1) # 可选:整理列顺序,删除中间辅助列 df = df[['item', 'quarter', 'value', 'value_prev']]
验证结果
执行后得到的结果与预期一致:
item quarter value value_prev 0 A FY20_Q1 100 NaN 1 A FY20_Q2 150 NaN 2 A FY20_Q3 120 NaN 3 A FY20_Q4 135 NaN 4 A FY21_Q1 128 100.0 5 A FY21_Q2 160 150.0 ...
月度数据的类似逻辑处理
如果是月度数据(如格式为FY20_01或2020-01),逻辑完全一致:
- 拆分出年份和月份编号;
- 按
item+month分组后执行shift(1)得到上年同月值; - 如果需要月度环比(MoM,即上月值),则直接按
item分组后执行shift(1)即可。
示例代码(假设月度数据格式为YYYY-MM):
# 模拟月度数据 month_df = pd.DataFrame({'item':['A','A','A','A'], 'month':['2020-01','2020-02','2021-01','2021-02'], 'value':[100,120,110,130]}) # 上年同月(YoY) month_df[['year', 'month_num']] = month_df['month'].str.split('-', expand=True).astype(int) month_df['value_prev_year'] = month_df.groupby(['item', 'month_num'])['value'].shift(1) # 月度环比(MoM) month_df['value_prev_month'] = month_df.sort_values(by=['item', 'month']).groupby(['item'])['value'].shift(1)
内容的提问来源于stack exchange,提问作者mockash
相关产品推荐
相关产品推荐

