pyspark.sql.functions
имеет очень удобную функцию с именем next_day
, которая делает именно то, что вы хотите. Требуется дата и день недели, который вы хотите найти. Создание правильной контрольной даты для этой функции может быть немного сложным, я сделал это так:
df.withColumn("firstDayOfYear", to_date(concat(col("year"), lit("-1-1"))))\
.withColumn("realtiveWeekDay", expr("date_add(firstDayOfYear, (week - 1) * 7)"))\
.withColumn("Sunday", next_day("realtiveWeekDay", "Sun")).show()
То, что я делаю здесь, сначала создаю первый день года, а затем нахожу соответствующий день в желаемомнеделю, а затем запустить next_day
, чтобы получить в следующее воскресенье. У этого подхода есть одна проблема - крайние случаи, как вы можете видеть ниже.
+----+----+--------------+---------------+----------+
|year|week|firstDayOfYear|realtiveWeekDay| Sunday|
+----+----+--------------+---------------+----------+
|2019| 1| 2019-01-01| 2019-01-01|2019-01-06|
|2019| 2| 2019-01-01| 2019-01-08|2019-01-13|
|2019| 53| 2019-01-01| 2019-12-31|2020-01-05|
|2018| 1| 2018-01-01| 2018-01-01|2018-01-07|
|2017| 1| 2017-01-01| 2017-01-01|2017-01-08|
|2017| 2| 2017-01-01| 2017-01-08|2017-01-15|
+----+----+--------------+---------------+----------+
В 2017 году 1 января было воскресенье - поэтому я понимаю, что воскресенье первой недели, которое вы хотите найти, на самом деле 2017.1.1.1,Когда мы передали его в next_day
, мы получим в следующее воскресенье после текущего. Чтобы исправить это, мы можем добавить дополнительную логику:
df.withColumn("firstDayOfYear", to_date(concat(col("year"), lit("-1-1"))))\
.withColumn("realtiveWeekDay", expr("date_add(firstDayOfYear, (week - 1) * 7)"))\
.withColumn("AdjustedSunday", when(dayofweek("realtiveWeekDay") == 1, col("realtiveWeekDay")).otherwise(next_day("realtiveWeekDay", "Sun")))\
.select("year", "week", "AdjustedSunday").show()
Это даст вам правильные результаты:
+----+----+--------------+
|year|week|AdjustedSunday|
+----+----+--------------+
|2019| 1| 2019-01-06|
|2019| 2| 2019-01-13|
|2019| 53| 2020-01-05|
|2018| 1| 2018-01-07|
|2017| 1| 2017-01-01|
|2017| 2| 2017-01-08|
+----+----+--------------+
Следует отметить, что в конце года последнийвоскресенье недели может быть в следующем году. Возможно, вы захотите обработать этот случай особым образом.
Выше код предполагает, что вы импортировали все используемые функции из pyspark.sql.functions
, поэтому вы можете захотеть сделать
from pyspark.sql.functions import *