2016-11-17 3 views
2

Примечание: У меня это как Dataframe в искры. Эти значения времени/даты составляют один столбец в Dataframe.Как отсортировать столбец со значениями даты и времени в Spark?

Вход:

04-ноября-16 03.36.13.000000000 PM
06-ноября-15 03.42.21.000000000 PM
05-ноября-15 03.32.05.000000000 PM
06-ноября-15 03.32.14.000000000 AM

Ожидаемый выход:

05-NOV-15 03.32.05.000000000 PM 
06-NOV-15 03.32.14.000000000 AM 
06-NOV-15 03.42.21.000000000 PM 
04-NOV-16 03.36.13.000000000 PM 
+0

вы пробовали что-нибудь? – mtoto

+0

Да. Пробное литье. Это не сработало. –

+0

scala или python? –

ответ

9

Поскольку этот формат не является стандартным, вы должны использовать UNIX_TIMESTAMP функцию, чтобы разобрать строку и преобразовать в тип временной метки:

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

// Example data 
val df = Seq(
    Tuple1("04-NOV-16 03.36.13.000000000 PM"), 
    Tuple1("06-NOV-15 03.42.21.000000000 PM"), 
    Tuple1("05-NOV-15 03.32.05.000000000 PM"), 
    Tuple1("06-NOV-15 03.32.14.000000000 AM") 
).toDF("stringCol") 

// Timestamp pattern found in string 
val pattern = "dd-MMM-yy hh.mm.ss.S a" 

// Creating new DataFrame and ordering 
val newDF = df 
    .withColumn("timestampCol", unix_timestamp(df("stringCol"), pattern).cast("timestamp")) 
    .orderBy("timestampCol") 

newDF.show(false) 

Результат:

+-------------------------------+---------------------+ 
|stringCol      |timestampCol   | 
+-------------------------------+---------------------+ 
|05-NOV-15 03.32.05.000000000 PM|2015-11-05 15:32:05.0| 
|06-NOV-15 03.32.14.000000000 AM|2015-11-06 03:32:14.0| 
|06-NOV-15 03.42.21.000000000 PM|2015-11-06 15:42:21.0| 
|04-NOV-16 03.36.13.000000000 PM|2016-11-04 15:36:13.0| 
+-------------------------------+---------------------+ 

Подробнее о UNIX_TIMESTAMP и другие утилиты функции можно найти here.

Для построения формата временных меток, можно обратиться к SimpleDateFormatter docs


Edit 1: как сказал pheeleeppoo, вы можете заказать непосредственно выражением, вместо того, чтобы создать новый столбец, предполагается, что вы хотите сохранить только строку типизированный столбец в вашем dataframe:

val newDF = df.orderBy(unix_timestamp(df("stringCol"), pattern).cast("timestamp")) 

Редактирование 2: Пожалуйста, обратите внимание, что точность функции UNIX_TIMESTAMP в секундах, так что если миллисекунды действительно важны, UDF может быть использован:

def myUDF(p: String) = udf(
    (value: String) => { 
    val dateFormat = new SimpleDateFormat(p) 
    val parsedDate = dateFormat.parse(value) 
    new java.sql.Timestamp(parsedDate.getTime()) 
    } 
) 

val pattern = "dd-MMM-yy hh.mm.ss.S a" 
val newDF = df.withColumn("timestampCol", myUDF(pattern)(df("stringCol"))).orderBy("timestampCol") 
+1

Спасибо тонну ..! Это сработало .. :) –

+0

@ Daniel de Paula: Спасибо за шаблон для вышеуказанного формата даты, но как это работает, даже если дата имеет AM или PM? – Shankar

+2

@Shankar в нижнем регистре «hh» в шаблоне указывает, что час должен быть между 0 и 12. Затем последний «a» в шаблоне указывает, что синтаксический анализатор найдет «AM» или «PM», который затем определить правильное время. Вот документ для шаблона: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html –

1

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

df.sort(unix_timestamp(df("dateColumn"), "dd-MMM-yy hh.mm.ss.S a").cast("timestamp")) 
    .show(false) 
+0

Практически никакого отличия от моего ответа. 'orderBy' и' sort' в основном одинаковы, с той разницей, что первая может использоваться в искровом свете <2.0. Было бы более ценным в качестве комментария для улучшения другого ответа, говорящего о том, что функция unix_timestamp может использоваться непосредственно внутри orderBy вместо использования в 'withColumn'. –

+0

Это была моя цель, на самом деле. – pheeleeppoo

+2

Похоже, акцент делается на функции ** sort **. Кроме того, шаблон неправильный, верхний регистр H для 24-часового формата. –

Смежные вопросы