如何在 PySpark 数据帧列中将日期转换为每月的第一天?



>我有以下数据帧:

+----------+
|      date|
+----------+
|2017-01-25|
|2017-01-21|
|2017-01-12|
+----------+

下面是在数据帧上创建的代码:

import pyspark.sql.functions as f
rdd = sc.parallelize([("2017/11/25",), ("2017/12/21",), ("2017/09/12",)])
df = sqlContext.createDataFrame(rdd, ["date"]).withColumn("date", f.to_date(f.col("date"), "yyyy/MM/dd"))
df.show()

我想要一个新列,每行都有每月的第一个日期,只需将所有日期中的日期替换为"01">

+----------++----------+
|      date| first_date|
+----------++----------+
|2017-11-25| 2017-11-01|
|2017-12-21| 2017-12-01|
|2017-09-12| 2017-09-01|
+----------+-----------+

PySpark.sql.function中有一个last_day函数,但是没有first_day函数。

我尝试使用 date_sub 来执行此操作,但没有奏效:我收到一个列不可迭代错误,因为要date_sub的第二个参数不能是列,必须是整数。

f.date_sub(f.col('date'), f.dayofmonth(f.col('date')) - 1 )

您可以使用trunc

import pyspark.sql.functions as f
df.withColumn("first_date", f.trunc("date", "month")).show()
+----------+----------+
|      date|first_date|
+----------+----------+
|2017-11-25|2017-11-01|
|2017-12-21|2017-12-01|
|2017-09-12|2017-09-01|
+----------+----------+

您可以使用提到的trunc函数(如Alper)或date_trunc方法获取月初。trunc函数返回日期列,date_trunc函数返回时间列。 假设您有以下数据帧:

+----------+
| some_date|
+----------+
|2017-11-25|
|2017-12-21|
|2017-09-12|
|      null|
+----------+

运行truncdate_trunc函数:

datesDF
.withColumn("beginning_of_month_date", trunc(col("some_date"), "month"))
.withColumn("beginning_of_month_time", date_trunc("month" ,col("some_date")))
.show()

观察结果:

+----------+-----------------------+-----------------------+
| some_date|beginning_of_month_date|beginning_of_month_time|
+----------+-----------------------+-----------------------+
|2017-11-25|             2017-11-01|    2017-11-01 00:00:00|
|2017-12-21|             2017-12-01|    2017-12-01 00:00:00|
|2017-09-12|             2017-09-01|    2017-09-01 00:00:00|
|      null|                   null|                   null|
+----------+-----------------------+-----------------------+

打印架构以确认列类型:

root
|-- some_date: date (nullable = true)
|-- beginning_of_month_date: date (nullable = true)
|-- beginning_of_month_time: timestamp (nullable = true)

Scala 用户应该使用 spark-daria 中定义的beginningOfMonthDatebeginningOfMonthTime函数。

PySpark 用户应使用 quinn 中定义的beginning_of_month_datebeginning_of_month_time函数。

请注意,trunc函数如何首先获取列参数,date_trunc如何先获取列参数,然后获取列参数。trunc方法的名称很差 - 它是函数包的一部分,因此很容易错误地认为此函数用于字符串截断。 令人惊讶的是,date_trunc返回时间戳结果...听起来它应该返回日期结果。

只需确保用描述性函数/UDF 名称包装这些函数,以便您的代码可读。 有关更多信息,请参阅此处。

我想这是语法错误,您能否更改f.dayofmonth -> dayofmonth并尝试。表情看起来很好。

import pyspark.sql.functions as f
f.date_sub(f.col('Match_date'),dayofmonth(f.col('Match_date')) - 1 ) 

最新更新