2016-05-04 20 views
15

Mam ramkę danych w Sparku z wieloma kolumnami i udf, które zdefiniowałem. Chcę ten sam ramka danych z powrotem, z wyjątkiem jednej przekształconej kolumny. Ponadto moje udf pobiera ciąg znaków i zwraca znacznik czasu. Czy istnieje prosty sposób na zrobienie tego? Spróbowałem:Spark Scala: Jak przekształcić kolumnę w DF

ale to zwraca RDD i tylko z przekształconą kolumną.

Odpowiedz

27

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_timestampcolumn 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

+1

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

+1

Dla iskry 1.5 należy pomnożyć przez 1000 przed obsadą –

+0

dzięki! zadziałało – mt88

Powiązane problemy