假设我有以下数据框 年周 2019 1 2019 2
我想得到第一周和第二周的星期天
年周日星期日
2019 1 20190106
2019 2 20190113
如何实现?
答案 0 :(得分:0)
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月1日是星期日-因此,我了解到您想查找的第一周星期日实际上是2017.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 *