it-swarm.com.ru

Фрейм данных PySpark конвертирует необычный формат строки в метку времени

Я использую PySpark через Spark 1.5.0 . У меня необычный формат String в строках столбца для значений даты и времени. Это выглядит так:

Row[(daytetime='2016_08_21 11_31_08')]

Есть ли способ преобразовать этот неортодоксальный формат yyyy_mm_dd hh_mm_dd во временную метку? Что-то, что в конечном итоге может прийти в соответствие с 

df = df.withColumn("date_time",df.daytetime.astype('Timestamp'))

Я думал, что функции Spark SQL, такие как regexp_replace, могут работать, но, конечно, мне нужно заменить _ на - в половине даты .__ и _ на : во временной части.

Я думал, что смогу разбить столбец на 2, используя substring, и отсчитывать в обратном направлении с конца времени. Затем выполните 'regexp_replace' отдельно, затем объедините. Но это кажется многим операциям? Есть ли более простой способ?

14
PR102012

Spark> = 2.2

from pyspark.sql.functions import to_timestamp

(sc
    .parallelize([Row(dt='2016_08_21 11_31_08')])
    .toDF()
    .withColumn("parsed", to_timestamp("dt", "yyyy_MM_dd hh_mm_ss"))
    .show(1, False))

## +-------------------+-------------------+
## |dt                 |parsed             |
## +-------------------+-------------------+
## |2016_08_21 11_31_08|2016-08-21 11:31:08|
## +-------------------+-------------------+

Spark <2.2

Это ничего, что unix_timestamp не может обработать:

from pyspark.sql import Row
from pyspark.sql.functions import unix_timestamp

(sc
    .parallelize([Row(dt='2016_08_21 11_31_08')])
    .toDF()
    .withColumn("parsed", unix_timestamp("dt", "yyyy_MM_dd hh_mm_ss")
    .cast("double")
    .cast("timestamp"))
    .show(1, False))

## +-------------------+---------------------+
## |dt                 |parsed               |
## +-------------------+---------------------+
## |2016_08_21 11_31_08|2016-08-21 11:31:08.0|
## +-------------------+---------------------+

В обоих случаях строка формата должна быть совместима с Java SimpleDateFormat .

31
zero323

ответ на ноль323 отвечает на вопрос, но я хотел бы добавить, что если ваша строка даты и времени имеет стандартный формат, вы сможете преобразовать ее непосредственно в тип метки времени:

df.withColumn('datetime', col('datetime_str').cast('timestamp'))

Он имеет преимущество обработки миллисекунд , тогда как unix_timestamp имеет только вторую точность (to_timestamp работает также с миллисекундами, но требует Spark> = 2.2, как указано в нуле 323). Я протестировал его на Spark 2.3.0, используя следующий формат: «2016-07-13 14: 33: 53.979» (с миллисекундами, но он также работает и без них).

1
Florent F

Я полностью согласен с выбранным ответом, однако я хотел бы установить формат 'yyyy_MM_dd HH_mm_ss', чтобы избежать проблем с метками времени, такими как '2019_01_27 16_00_00' -> Note note> 12

0
Pedro Muñoz