【问题标题】:How to add days (as values of a column) to date?如何将天数(作为列的值)添加到日期?
【发布时间】:2018-04-12 15:15:25
【问题描述】:

在 Spark 中向日期格式列添加天数(数字)时遇到问题。我知道有一个函数date_add 接受两个参数 - 日期列和整数:

date_add(date startdate, tinyint/smallint/int days)

我想改用整数类型的列值(不是整数本身)。

假设我有以下数据框:

val data = Seq(
    (0, "2016-01-1"),
    (1, "2016-02-2"),
    (2, "2016-03-22"),
    (3, "2016-04-25"),
    (4, "2016-05-21"),
    (5, "2016-06-1"),
    (6, "2016-03-21"))
).toDF("id", "date")

我可以简单地将整数添加到日期:

val date_add_fun = 
data.select(
    $"id",
    $"date",
    date_add($"date", 1)
)

但我不能使用包含值的列表达式:

val date_add_fun = 
data.select(
    $"id",
    $"date",
    date_add($"date", $"id")
)

报错:

<console>:60: error: type mismatch;
 found   : org.apache.spark.sql.ColumnName
 required: Int
           date_add($"date", $"id")

有谁知道是否可以使用 column is date_add 函数?或者有什么解决方法?

【问题讨论】:

    标签: scala apache-spark apache-spark-sql


    【解决方案1】:

    你可以使用expr:

    import org.apache.spark.sql.functions.expr
    
    data.withColumn("future", expr("date_add(date, id)")).show
    // +---+----------+----------+
    // | id|      date|    future|
    // +---+----------+----------+
    // |  0| 2016-01-1|2016-01-01|
    // |  1| 2016-02-2|2016-02-03|
    // |  2|2016-03-22|2016-03-24|
    // |  3|2016-04-25|2016-04-28|
    // |  4|2016-05-21|2016-05-25|
    // |  5| 2016-06-1|2016-06-06|
    // |  6|2016-03-21|2016-03-27|
    // +---+----------+----------+
    

    selectExpr 可以以类似的方式使用:

    data.selectExpr("*", "date_add(date, id) as future").show
    

    【讨论】:

      【解决方案2】:

      其他答案有效,但不能替代现有的 date_add 函数。 我有一个案例,expr 不适合我,所以这里有一个替代品:

      def date_add(date: Column, days: Column) = {
          new Column(DateAdd(date.expr, days.expr))
      }
      

      基本上,Spark 中的所有机制都可以做到这一点,date_add 的函数签名只是强制它成为文字。

      【讨论】:

      • 被低估的答案。此外,真的很愚蠢,它迫使列变成文字。听起来好像没有经过审查或其他什么。
      • 对于在这里的Python开发者,您可以简单地使用+将一个数据列添加到另一个列中
      【解决方案3】:

      您可以使用 sql 表达式作为

      data.createOrReplaceTempView("table")
      sqlContext.sql("select id, date, date_add(`date`, `id`) as added_date from table").show(false)
      

      这会给你

      +---+----------+----------+
      |id |date      |added_date|
      +---+----------+----------+
      |0  |2016-01-1 |2016-01-01|
      |1  |2016-02-2 |2016-02-03|
      |2  |2016-03-22|2016-03-24|
      |3  |2016-04-25|2016-04-28|
      |4  |2016-05-21|2016-05-25|
      |5  |2016-06-1 |2016-06-06|
      |6  |2016-03-21|2016-03-27|
      +---+----------+----------+
      

      【讨论】:

        【解决方案4】:

        对于这里的 Python 开发人员,您可以简单地使用 + 将日期列添加到另一列中:

        import pyspark.sql.functions as F
        
        new_df = df.withColumn("new_date", F.col("date") + F.col("offset"))
        

        只需确保偏移列是 int/smallint/tinyint。

        【讨论】:

          猜你喜欢
          • 2011-01-20
          • 2011-04-18
          • 2014-05-25
          • 1970-01-01
          • 1970-01-01
          • 2010-10-08
          • 2020-05-23
          • 1970-01-01
          相关资源
          最近更新 更多