PySpark Миллисекунды TimeStamp - PullRequest
0 голосов
/ 01 марта 2019

Я пытаюсь получить разницу между двумя столбцами отметок времени, но миллисекунды пропали.

Как исправить это?

from pyspark.sql.functions import unix_timestamp
timeFmt = "yyyy-MM-dd' 'HH:mm:ss.SSS"

data = [
    (1, '2018-07-25 17:15:06.39','2018-07-25 17:15:06.377'),
    (2,'2018-07-25 11:12:49.317','2018-07-25 11:12:48.883')

]

df = spark.createDataFrame(data, ['ID', 'max_ts','min_ts']).withColumn('diff',F.unix_timestamp('max_ts', format=timeFmt) - F.unix_timestamp('min_ts', format=timeFmt))
df.show(truncate = False)

Ответы [ 2 ]

0 голосов
/ 27 мая 2019

Ответ от Tanjin не работает, когда значения имеют тип timestamp, а миллисекунды представляют собой круглые числа (например, 390, 500).Python обрезает 0 в конце, и временная метка из примера будет выглядеть так: 2018-07-25 17:15:06.39.

Проблема заключается в жестко заданном значении в F.substring('max_ts', -3, 3).Если 0 в конце отсутствует, то substring становится диким.

Чтобы преобразовать tmpColumn столбца типа timestamp в tmpLongColumn типа long Я использовал этот фрагмент:

timeFmt = "yyyy-MM-dd HH:mm:ss.SSS"

df = df \
  .withColumn('tmpLongColumn', F.substring_index('tmpColumn', '.', -1).cast('float')) \
  .withColumn('tmpLongColumn', F.when(F.col('tmpLongColumn') < 100, F.col('tmpLongColumn')*10).otherwise(F.col('tmpLongColumn')).cast('long')) \
  .withColumn('tmpLongColumn', (F.unix_timestamp('tmpColumn', format=timeFmt)*1000 + F.col('tmpLongColumn'))) \

Первое преобразование извлекает подстроку, содержащую миллисекунды.Затем, если значение меньше 100, умножьте его на 10. Наконец, преобразуйте метку времени и добавьте миллисекунды.

0 голосов
/ 02 марта 2019

Это предполагаемое поведение для unix_timestamp - оно ясно указывает в строке документа исходного кода , что возвращает только секунды, поэтому компонент миллисекунд пропадает при выполнении вычисления.

Если выЕсли вы хотите выполнить этот расчет, вы можете использовать функцию substring для вычисления чисел, а затем сделать разницу.Смотрите пример ниже.Обратите внимание, что это предполагает полностью сформированные данные, например, миллисекунды выполняются полностью (все 3 цифры):

import pyspark.sql.functions as F

timeFmt = "yyyy-MM-dd' 'HH:mm:ss.SSS"
data = [
    (1, '2018-07-25 17:15:06.390', '2018-07-25 17:15:06.377'),  # note the '390'
    (2, '2018-07-25 11:12:49.317', '2018-07-25 11:12:48.883')
]

df = spark.createDataFrame(data, ['ID', 'max_ts', 'min_ts'])\
    .withColumn('max_milli', F.unix_timestamp('max_ts', format=timeFmt) + F.substring('max_ts', -3, 3).cast('float')/1000)\
    .withColumn('min_milli', F.unix_timestamp('min_ts', format=timeFmt) + F.substring('min_ts', -3, 3).cast('float')/1000)\
    .withColumn('diff', (F.col('max_milli') - F.col('min_milli')).cast('float') * 1000)

df.show(truncate=False)

+---+-----------------------+-----------------------+----------------+----------------+---------+
|ID |max_ts                 |min_ts                 |max_milli       |min_milli       |diff     |
+---+-----------------------+-----------------------+----------------+----------------+---------+
|1  |2018-07-25 17:15:06.390|2018-07-25 17:15:06.377|1.53255330639E9 |1.532553306377E9|13.000011|
|2  |2018-07-25 11:12:49.317|2018-07-25 11:12:48.883|1.532531569317E9|1.532531568883E9|434.0    |
+---+-----------------------+-----------------------+----------------+----------------+---------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...