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

如何计算周度同比数据?适配含53周年份的对齐方案

周度同比计算适配53周年份的解决方案

需要计算周度经济指数(WEI)的同比数据,但部分年份存在53周(如2011、2016、2022年),要求这些年份的第53周与前一年的第52周做同比对比,解决周数对齐问题。现有的calculate_week_on_week函数用shift(52)实现,无法适配该场景,以下是可行的适配方案。


现有代码与数据情况

数据读取与日期处理代码

import pandas as pd
df = pd.read_excel('../raw_data/WEI.xls', skiprows=10)
df['observation_date'] = pd.to_datetime(df['observation_date'])

def add_date_parts(df, date_column):
     df['year_week_ori'] = df[date_column].dt.strftime('%Y-%V')
     df['year'] = df[date_column].dt.isocalendar().year
     df['week'] = df[date_column].dt.isocalendar().week
     df.loc[df['week'] > 52, 'week'] = 52
     df['year_week_modified'] = df['year'].astype(str) + '-' + df['week'].astype(str).str.zfill(2)
     df['year'] = df[date_column].dt.year
     df['month'] = df[date_column].dt.month
     return df

df = add_date_parts(df, 'observation_date')

处理后的数据样例

observation_date   WEI year_week_ori  year  week year_week_modified  month
0         2008-01-05  1.80       2008-01  2008     1            2008-01      1
1         2008-01-12  1.78       2008-02  2008     2            2008-02      1
2         2008-01-19  1.75       2008-03  2008     3            2008-03      1
3         2008-01-26  1.28       2008-04  2008     4            2008-04      1
4         2008-02-02  0.99       2008-05  2008     5            2008-05      2
..               ...   ...           ...   ...   ...                ...    ...
817       2023-09-02  1.72       2023-35  2023    35            2023-35      9
818       2023-09-09  1.72       2023-36  2023    36            2023-36      9
819       2023-09-16  2.17       2023-37  2023    37            2023-37      9
820       2023-09-23  1.62       2023-38  2023    38            2023-38      9
821       2023-09-30  1.83       2023-39  2023    39            2023-39      9
[822 rows x 7 columns]

各年份周数统计

df.groupby('year')['WEI'].count()

输出:

year
2008    52
2009    52
2010    52
2011    53
2012    52
2013    52
2014    52
2015    52
2016    53
2017    52
2018    52
2019    52
2020    52
2021    52
2022    53
2023    39

未适配的同比计算函数

def calculate_week_on_week(df, value_column, date_column):
    df = df.sort_values(date_column)
    df['value_last_year'] = df[value_column].shift(52)
    df['week_on_week'] = (df[value_column] - df['value_last_year'])/df['value_last_year']
    return df

适配方案

方案一:基于修改后的年周标识匹配

利用已生成的year_week_modified字段,直接匹配去年对应的周数(第53周自动对应去年第52周),逻辑直观不易出错。

def calculate_week_on_year_adjusted(df, value_column, date_column):
    # 确保数据按日期排序
    df = df.sort_values(date_column).reset_index(drop=True)
    
    # 生成去年对应的年周匹配键
    def get_last_year_key(row):
        current_year, current_week = row['year_week_modified'].split('-')
        last_year = str(int(current_year) - 1)
        return f"{last_year}-{current_week}"
    
    df['last_year_key'] = df.apply(get_last_year_key, axis=1)
    
    # 创建年周键到数值的映射表
    week_value_map = df.set_index('year_week_modified')[value_column].to_dict()
    
    # 匹配去年对应周的数值
    df['value_last_year'] = df['last_year_key'].map(week_value_map)
    
    # 计算同比增长率
    df['week_on_year'] = (df[value_column] - df['value_last_year']) / df['value_last_year']
    
    # 清理临时列
    df = df.drop(columns=['last_year_key'])
    
    return df

方案二:动态计算偏移量

通过统计历史53周年份的数量,动态调整shift的偏移量,不需要依赖额外的年周标识列。

def calculate_week_on_year_shift_adjusted(df, value_column, date_column):
    df = df.sort_values(date_column).reset_index(drop=True)
    
    # 统计各年份的周数
    year_week_counts = df.groupby('year')['week'].count().to_dict()
    
    # 计算累计偏移调整量:每遇到一个历史53周年份,偏移量加1
    df['adjustment'] = 0
    for i in range(1, len(df)):
        prev_years = df.loc[:i-1, 'year'].unique()
        df.loc[i, 'adjustment'] = sum(1 for y in prev_years if year_week_counts.get(y, 52) == 53)
    
    # 计算最终偏移量并匹配去年数值
    df['value_last_year'] = df[value_column].shift(52 + df['adjustment'])
    
    # 计算同比增长率
    df['week_on_year'] = (df[value_column] - df['value_last_year']) / df['value_last_year']
    
    # 清理临时列
    df = df.drop(columns=['adjustment'])
    
    return df

内容的提问来源于stack exchange,提问作者ah bon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:07:03