2016-05-05 26 views
5

Ho due colonne di data/ora in un dataframe che vorrei ottenere la differenza minima di, o in alternativa, la differenza di ora di. Attualmente sono in grado di ottenere la differenza il giorno, con arrotondamento, facendoScala Scala: DateDiff di due colonne per ora o minuto

val df2 = df1.withColumn("time", datediff(df1("ts1"), df1("ts2"))) 

Tuttavia, quando ho guardato la pagina doc https://issues.apache.org/jira/browse/SPARK-8185 non ho visto alcun parametro in più per cambiare l'unità. È una loro funzione diversa che dovrei usare per questo?

risposta

9

si può ottenere la differenza in pochi secondi

import org.apache.spark.sql.functions._ 
val diff_secs_col = col("ts1").cast("long") - col("ts2").cast("long") 

Poi si può fare un po 'di matematica per ottenere l'unità desiderata. Per esempio:

val df2 = df1 
    .withColumn("diff_secs", diff_secs_col) 
    .withColumn("diff_mins", diff_secs_col/60D) 
    .withColumn("diff_hrs", diff_secs_col/3600D) 
    .withColumn("diff_days", diff_secs_col/(24D * 3600D)) 

O, in pyspark:

from pyspark.sql.functions import * 
diff_secs_col = col("ts1").cast("long") - col("ts2").cast("long") 

df2 = df1 \ 
    .withColumn("diff_secs", diff_secs_col) \ 
    .withColumn("diff_mins", diff_secs_col/60D) \ 
    .withColumn("diff_hrs", diff_secs_col/3600D) \ 
    .withColumn("diff_days", diff_secs_col/(24D * 3600D)) 
0

La risposta data da Daniel de Paula opere, ma questa soluzione non funziona nel caso in cui è necessaria la differenza per ogni riga nel tuo tavolo Ecco una soluzione che farà per ogni riga:

import org.apache.spark.sql.functions 

val df2 = df1.selectExpr("(unix_timestamp(ts1) - unix_timestamp(ts2))/3600") 

Questa prima converte i dati nelle colonne a un timestamp unix in secondi, li sottrae quindi converte la differenza di ore.

un utile elenco di funzioni sono disponibili all'indirizzo: http://spark.apache.org/docs/latest/api/scala/#org.apache.spark.sql.functions $

+1

La mia soluzione calcolerà la differenza per ogni riga nel dataframe. Si prega di essere più specifico se c'è un problema con esso. Inoltre, per la tua soluzione, credo sarebbe meglio evitare le espressioni di stringa (è più difficile da testare e più incline agli errori): 'val df2 = df1.select ((unix_timestamp (ts1) - unix_timestamp (ts2))/3600D)' . –