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

基于自定义起始日期生成DataFrame年度周数的异常问题及解决需求

自定义年度周计算方案(起始日2021-06-28)

针对你的需求,我们可以完全自定义周数的计算逻辑,摆脱ISO周的限制,同时准确标记自定义年度前后的日期为LYxx(上一年周数)或NYxx(下一年周数),也可以用数字形式的负周数/52+周数来满足聚合需求。

核心思路

  1. 明确自定义年度区间:
    • 基准年度:2021-06-28 ~ 2022-06-27(共365天,对应周数1~52)
    • 上一个自定义年度:2020-06-28 ~ 2021-06-27(周数标记为LY1~LY52)
    • 下一个自定义年度:2022-06-28 ~ 2023-06-27(周数标记为NY1~NY52)
  2. 计算每个日期与对应自定义年度起始日的天数差,转换为周数(每周从周一开始,7天为一周)
  3. 根据日期所属区间,添加对应的前缀或数字偏移,确保聚合时不会出现异常分组

完整代码实现

import pandas as pd

# 1. 准备示例数据(替换为你的实际DataFrame)
data = {
    'date': ['2021-03-12', '2021-03-17', '2021-06-28', '2022-05-21', '2022-08-17']
}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])

# 2. 定义自定义年度核心参数
base_start = pd.to_datetime('2021-06-28')
year_duration = pd.DateOffset(years=1)  # 自动适配闰年,无需手动调整天数

# 3. 计算每个日期与基准起始日的天数差
df['days_from_base'] = (df['date'] - base_start).dt.days

# 4. 确定日期所属的自定义年度类型
def get_year_type(days_diff):
    if 0 <= days_diff < year_duration.days:
        return 'base'  # 基准年度
    elif days_diff < 0:
        return 'last'  # 上一个自定义年度
    else:
        return 'next'  # 下一个自定义年度

df['year_type'] = df['days_from_base'].apply(get_year_type)

# 5. 计算对应年度内的周数
def calculate_week(row):
    if row['year_type'] == 'base':
        # 基准年度:从base_start开始,每7天为一周,第1周是base_start所在周
        return (row['days_from_base'] // 7) + 1
    elif row['year_type'] == 'last':
        # 上一年度:从base_start往前推1年的起始日计算周数
        last_year_start = base_start - year_duration
        days_from_last_start = (row['date'] - last_year_start).days
        return (days_from_last_start // 7) + 1
    else:
        # 下一年度:从base_start往后推1年的起始日计算周数
        next_year_start = base_start + year_duration
        days_from_next_start = (row['date'] - next_year_start).days
        return (days_from_next_start // 7) + 1

df['week_num'] = df.apply(calculate_week, axis=1)

# 6. 生成最终的year_week列(两种格式可选)
# 格式1:带前缀的字符串(直观易读)
df['year_week_str'] = df.apply(
    lambda row: f"LY{row['week_num']}" if row['year_type'] == 'last' 
                else f"NY{row['week_num']}" if row['year_type'] == 'next' 
                else str(row['week_num']),
    axis=1
)

# 格式2:数字格式(便于数值聚合和排序)
df['year_week_num'] = df.apply(
    lambda row: -row['week_num'] if row['year_type'] == 'last' 
                else 52 + row['week_num'] if row['year_type'] == 'next' 
                else row['week_num'],
    axis=1
)

# 查看结果
print(df[['date', 'year_week_str', 'year_week_num']])

输出结果

date year_week_str  year_week_num
0 2021-03-12          LY38            -38
1 2021-03-17          LY39            -39
2 2021-06-28             1              1
3 2022-05-21            47             47
4 2022-08-17           NY8             60

关键说明

  • 完全匹配你的预期:2021-03-12标记为LY38,2022-08-17标记为NY8,基准年度内的日期周数计算准确
  • 自动适配闰年:使用pd.DateOffset(years=1)替代固定365天,无需担心闰年导致的周数偏差
  • 两种格式灵活选择:字符串格式适合人工查看,数字格式适合后续的聚合分析和排序

内容的提问来源于stack exchange,提问作者Jonas Palačionis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:47:31