【发布时间】:2021-07-23 00:21:18
【问题描述】:
我需要添加一个包含日期列的列,该列将是该周星期一的日期。 我有一列已经有周数了。
我如何使用 pyspark 或 spark sql 来实现它。
示例:周数:28
第 28 周的星期一的日期为:2021-07-12
【问题讨论】:
标签: sql pyspark apache-spark-sql
我需要添加一个包含日期列的列,该列将是该周星期一的日期。 我有一列已经有周数了。
我如何使用 pyspark 或 spark sql 来实现它。
示例:周数:28
第 28 周的星期一的日期为:2021-07-12
【问题讨论】:
标签: sql pyspark apache-spark-sql
您可以在日期上使用 to_date 函数,并连接 1(星期几:星期一),例如 202129,其中 2021 是年份,29 是一年中的一周,1 是星期几。有关日期时间字符的信息,请参阅Java Simple Date 格式。
注意 - 不知何故,to_date 将日期转换为比正确星期早的一周,因此增加了 7 天来获得实际的星期一日期
例子-
sc = SparkContext.getOrCreate()
sql = SQLContext(sc)
sql.sql("set spark.sql.legacy.timeParserPolicy=LEGACY")
sparkDF = sql.createDataFrame([('1','202129')],[ "ID","date_weeknum"])
sparkDF = sparkDF.withColumn("new_date", F.to_date(F.concat("date_weeknum",F.lit("1")), "yyyywwu"))
sparkDF = sparkDF.withColumn("monday_date", F.date_add(F.col('new_date'),7))
sparkDF.show()
+---+------------+----------+-----------+
| ID|date_weeknum| new_date|monday_date|
+---+------------+----------+-----------+
| 1| 202129|2021-07-12| 2021-07-19|
+---+------------+----------+-----------+
sparkDF = sql.createDataFrame([('1','202129')],[ "ID","date_weeknum"])
sparkDF = sparkDF.withColumn("new_date", F.to_date(F.concat("date_weeknum",F.lit("1")), "yyyywwu"))
sparkDF = sparkDF.withColumn("monday_date", F.date_add(F.col('new_date'),7))
sparkDF.show()
+---+------------+----------+-----------+
| ID|date_weeknum| new_date|monday_date|
+---+------------+----------+-----------+
| 1| 202129|2021-07-12| 2021-07-19|
+---+------------+----------+-----------+
【讨论】:
我认为您有一个日期列,您可以从中获取周数。您还可以根据日期获取星期几。根据dayofweek 函数,天数默认从星期日为 1,星期一为 2 到星期六 7。我们将不得不应用一些自定义逻辑来更改此排序并将星期一的日期编号设为 1,星期二设为 2,直到星期日设为 7。
之后,我们可以从实际日期中减去天数,得到该周的星期一日期。
//sample dataframe creation
df = spark.createDataFrame([(1, "2021-07-11"),(2, "2021-07-15")], ['id', 'date'])
//getting the week number and the day number of the day in the week
from pyspark.sql.functions import *
df1 = df.withColumn("weeknumber",weekofyear(df.date))
.withColumn("day_of_week",dayofweek(df.date))
.withColumn("date_format", date_format(df.date, "EEEE"))
//subtracting the day number from the actual date to get the monday date for that week
df2 = df1.withColumn("Number", when (df1.day_of_week == 1, df1.day_of_week + 6 ).otherwise(df1.day_of_week - 1))
.selectExpr('*', 'date_sub(date, Number - 1) as week_start_monday')
display(df2)
【讨论】: