pyspark 如何使用Spark SQL获取3月的最后一个星期日

yc0p9oo0  于 2023-08-02  发布在  Spark
关注(0)|答案(2)|浏览(148)

我需要实现夏令时的逻辑。为了那个我需要得到每年三月的最后一个星期天。如何使用Spark SQL?
我应该得到每年三月最后一个星期天的凌晨1点。试过各种方法都不管用。

piok6c0g

piok6c0g1#

我觉得夏令时在这里不重要。你可以通过查找Apr/1的dayofweek来查找3月的最后一个星期日,然后从Apr/1中减去它。

from pyspark.sql import functions as F

df = spark.createDataFrame(data = [
    [2021],
    [2022],
    [2023]
], ['year'])

df = (df.withColumn('apr1', F.to_date(F.concat_ws('-', F.col('year'), F.lit('04-01'))))
      .withColumn('dow', F.dayofweek('apr1'))
      .withColumn('last_sun', F.to_timestamp(F.concat(F.expr('date_sub(apr1, dow-1)'), F.lit(' 01:00:00')))))

字符串
测试结果

+----+----------+---+-------------------+
|year|      apr1|dow|           last_sun|
+----+----------+---+-------------------+
|2021|2021-04-01|  5|2021-03-28 01:00:00|
|2022|2022-04-01|  6|2022-03-27 01:00:00|
|2023|2023-04-01|  7|2023-03-26 01:00:00|
+----+----------+---+-------------------+

xxe27gdn

xxe27gdn2#

以下是步骤:

  • 获取3月的最后一天(last_day列)
  • 将其转换为星期**(1=星期一,...,7 =星期日)**(last_day_number列)
  • 如果是7,那么三月的最后一天就是星期天
  • 否则,减去星期几的值,返回到最后一个星期日,这将是三月份的最后一个星期日

代码:

df = spark.createDataFrame(
        [(2019,), (2020,), (2021,), (2022,), (2023,)], ["year_col"]
    )

    df = (
        df.withColumn(
            "last_day", last_day(concat(col("year_col"), lit("-03-01")))
        )
        .withColumn(
            "last_day_number", date_format("last_day", "u") # 7 = Sunday
        )
        .withColumn(
            "last_sunday_of_march",
            when(
                col("last_day_number") == lit(7), col("last_day") # if last day of march is sunday, then it is the last sunday of march
            ).otherwise(
                expr("date_sub(last_day, last_day_number)") # else, subtract the number of days from the last day of march to get the last sunday of march
            ),
        )
    ).select("year_col", "last_sunday_of_march")

字符串
测试结果:

year_col last_sunday_of_march
      2019           2019-03-31
      2020           2020-03-29
      2021           2021-03-28
      2022           2022-03-27
      2023           2023-03-26

相关问题