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

PySpark中基于4月起始财年从日期列计算年度周数

嘿,这个问题我刚好处理过!Spark默认的weekofyear确实是按自然年(1月1日为起始)计算周数的,要改成以4月1日为财年起始的计算逻辑,我给你两种靠谱的方案,优先推荐第一种,因为能避开边界日期的坑:

方法一:基于财年起始日计算天数差(稳妥无边界问题)

这个方法的核心逻辑是先确定每个日期对应的财年起始日,再通过日期差计算周数,完全贴合财年的时间范围:

  1. 确定财年起始日:如果日期的月份≥4,财年起始就是当年的4月1日;如果月份<4,财年起始就是前一年的4月1日。
  2. 计算财年周数:用当前日期减去财年起始日的天数差,除以7取整后加1(因为第1天属于第1周)。

代码实现:

from pyspark.sql import functions as F

# 第一步:计算每个日期对应的财年起始日
df = df.withColumn(
    "fy_start",
    F.when(
        F.month("date") >= 4,
        # 生成当年4月1日:先截断到当年年初,再格式化为4月1日并转成日期类型
        F.to_date(F.date_format(F.date_trunc("year", "date"), "yyyy-04-01"))
    ).otherwise(
        # 生成前一年4月1日:截断到当年年初后减1年,再格式化为4月1日
        F.to_date(F.date_format(F.add_months(F.date_trunc("year", "date"), -12), "yyyy-04-01"))
    )
)

# 第二步:计算财年周数
df = df.withColumn(
    "week",
    # 天数差除以7取整,加1得到对应的财年周数
    F.floor(F.datediff("date", "fy_start") / 7) + 1
)

# 可选:如果不需要中间列fy_start,可以删掉它
df = df.drop("fy_start")

用你的示例数据验证一下:

  • 2018-08-12:财年起始是2018-04-01,天数差133天,133÷7=19,加1得20
  • 2019-01-23:财年起始是2018-04-01,天数差297天,297÷7≈42.43,取整42加1得43
  • 2019-04-03:财年起始是2019-04-01,天数差2天,取整0加1得1
方法二:日期偏移适配weekofyear(简洁但有边界局限)

如果你的业务场景可以接受ISO周的边界处理(比如财年末尾的日期可能被归为下财年第1周),可以用更简洁的方式:把日期减去3个月,这样4月1日就对应自然年的1月1日,直接用weekofyear计算即可:

from pyspark.sql import functions as F

df = df.withColumn(
    "week",
    F.weekofyear(F.add_months("date", -3))
)

⚠️ 注意:比如2020-03-31(属于2019财年最后一天),减去3个月是2019-12-31,weekofyear会返回1(因为这一天属于2020年的第1周),但实际它应该是2019财年的最后一周,这种边界情况需要额外调整,所以方法一更稳妥。

内容的提问来源于stack exchange,提问作者Pallavi Verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:44:27