Spark Scala: как преобразовать столбец в DF

У меня есть DataFrame в Spark со многими столбцами и udf, которые я определил. Я хочу, чтобы один и тот же файл данных возвращался, за исключением того, что один столбец был преобразован. Кроме того, мой udf берет строку и возвращает метку времени. Есть простой способ сделать это? Я попробовал

val test = myDF.select("my_column").rdd.map(r => getTimestamp(r)) 

но это возвращает RDD и только с преобразованным столбцом.

Ответы

Ответ 1

Если вам действительно нужно использовать вашу функцию, я могу предложить два варианта:

1) Использование map/toDF:

import org.apache.spark.sql.Row
import sqlContext.implicits._

def getTimestamp: (String => java.sql.Timestamp) = // your function here

val test = myDF.select("my_column").rdd.map {
  case Row(string_val: String) => (string_val, getTimestamp(string_val))
}.toDF("my_column", "new_column")

2) Использование UDF (UserDefinedFunction):

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

def getTimestamp: (String => java.sql.Timestamp) = // your function here

val newCol = udf(getTimestamp).apply(col("my_column")) // creates the new column
val test = myDF.withColumn("new_column", newCol) // adds the new column to original DF

Более подробная информация о Spark SQL UDFs в эта хорошая статья Билла Чамберса.


Альтернативно,

Если вы хотите преобразовать столбец StringType в столбец TimestampType, вы можете использовать функцию столбца unix_timestamp , поскольку Spark SQL 1.5:

val test = myDF
  .withColumn("new_column", unix_timestamp(col("my_column"), "yyyy-MM-dd HH:mm").cast("timestamp"))

Примечание. Для искры 1.5.x необходимо умножить результат unix_timestamp на 1000 перед тем, как выполнить кастинг в timestamp (issue SPARK-11724), Итоговый код:

val test = myDF
  .withColumn("new_column", (unix_timestamp(col("my_column"), "yyyy-MM-dd HH:mm") *1000L).cast("timestamp"))

Изменить: добавлена ​​опция udf