【问题标题】:How to convert date to the first day of month in a PySpark Dataframe column?如何将日期转换为 PySpark Dataframe 列中的第一天?
【发布时间】:2018-01-19 20:28:34
【问题描述】:

我有以下数据框:

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

下面是创建上面DataFrame的代码:

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 来执行此操作,但没有成功:我收到 column not Iterable 错误,因为 date_sub 的第二个参数不能是列并且必须是整数。

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

【问题讨论】:

    标签: python apache-spark pyspark apache-spark-sql


    【解决方案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|
    +----------+----------+
    

    【讨论】:

      【解决方案2】:

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

      +----------+
      | 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 名称包装这些函数,以便您的代码可读。请参阅here 了解更多信息。

      【讨论】:

        【解决方案3】:

        我想这是语法错误,你能改变 f.dayofmonth -> dayofmonth 并尝试。表情看起来不错。

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

        【讨论】:

          猜你喜欢
          • 2023-01-26
          • 2022-12-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多