Jeśli naprawdę potrzebujesz, aby korzystać z funkcji, mogę zaproponować dwie opcje:
1) Używanie 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) Korzystanie z 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
Jest więcej szczegółów na temat UDF w formacie Spark SQL w this nice article by Bill Chambers.
Alternatywnie,
Jeśli chcesz po prostu przekształcić kolumnę StringType
do kolumny TimestampType
można użyć unix_timestamp
column function dostępny od Spark SQL 1.5:
val test = myDF
.withColumn("new_column", unix_timestamp(col("my_column"), "yyyy-MM-dd HH:mm").cast("timestamp"))
Uwaga: W przypadku iskrzenie 1.5.x, konieczne jest pomnożenie wyniku unix_timestamp
przez 1000
przed rzutowaniem na znacznik czasu (iss ue SPARK-11724). Otrzymany kod byłoby:
val test = myDF
.withColumn("new_column", (unix_timestamp(col("my_column"), "yyyy-MM-dd HH:mm") *1000L).cast("timestamp"))
EDIT: Dodano opcję UDF
Dzięki za pomoc. Jedyny problem jaki mam to to, że kiedy robię df.withColumn ("start_date", unix_timestamp (df1 ("start_date"), "yyyy-MM-dd HH: mm: ss"). Cast ("znacznik czasu")) , moje daty są źle przeliczane. Na przykład: 2013-08-12 06:40:54 zostaje zmieniony na 1970-01-16 22: 18: 09.654. Czy zdajesz sobie sprawę, co się dzieje? – mt88
Dla iskry 1.5 należy pomnożyć przez 1000 przed obsadą –
dzięki! zadziałało – mt88