SpHow合并DataFrame列的两个字段(字符串类型)以生成Date

时间:2017-08-29 11:57:12

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

我有一个DataFrame,简化架构有两列,每列有3个字段:

root
 |-- npaDetails: struct (nullable = true)
 |    |-- additionalInformation: struct (nullable = true)
 |    |-- npaStatus: struct (nullable = true)
 |    |-- npaDetails: struct (nullable = true)
 |-- npaHeaderData: struct (nullable = true)
 |    |-- npaNumber: string (nullable = true)
 |    |-- npaDownloadDate: string (nullable = true)     
 |    |-- npaDownloadTime: string (nullable = true)     

可能的值:

npaDownloadDate - "30JAN17"
npaDownloadTime - "19.50.00"

我需要将DataFrame中的两行与此模式进行比较,以确定哪一行是“更新”。为此,我需要合并字段npaDownloadDatenpaDownloadTime以生成我可以轻松比较的日期。

下面是我到目前为止编写的代码。它有效,但我认为它需要的步骤多于必要的步骤,我确信Scala提供的解决方案比我的方法更好。

val parquetFileDF = sqlContext.read.parquet("MyParquet.parquet")

val relevantRows = parquetFileDF.filter($"npaHeaderData.npaNumber" === "123456")

val date = relevantRows .select($"npaHeaderData.npaDownloadDate").head().get(0)
val time = relevantRows .select($"npaHeaderData.npaDownloadTime").head().get(0)

val dateTime = new SimpleDateFormat("ddMMMyykk.mm.ss").(date+time)

//I would replicate the previous steps to get dateTime2
if(dateTime.before(dateTime2))
  println("dateTime is before dateTime2")

因此"30JAN17""19.50.00"的输出将为Mon Jan 30 19:50:00 GST 2017

是否有另一种方法可以从列的两个字段生成日期,而不提取并将它们合并为字符串?或者甚至更好,是否可以直接比较数据框中两个不同行之间的值(日期和时间),以了解哪个具有较旧的日期

2 个答案:

答案 0 :(得分:2)

在火花2.2中,

df.filter(
  to_date(
    concat(
      $"npaHeaderData.npaDownloadDate",
      $"npaHeaderData.npaDownloadTime"),
    fmt = "[your format here]")
  ) < lit(some date))

答案 1 :(得分:1)

我使用

import org.apache.spark.sql.functions._

df.withColumn("some_name", date_format(unix_timestamp(
  concat($"npaHeaderData.npaDownloadDate", $"npaHeaderData.npaDownloadTime"),
 "ddMMMyykk.mm.ss").cast("timestamp"),
 "EEE MMM d HH:mm:ss z yyyy"))