Работа с микросекундными метками времени в PySpark

Когда я пробовал разницу между тем же штампом времени, он дал 0 дней 5 часов 30 минут

, поэтому, чтобы получить его точно, я вычитал 5 часов и 30 минут

function get_time_diff( datetime )
{
var datetime = typeof datetime !== 'undefined' ? datetime : "2014-01-01 01:02:03.123456";

var datetime = new Date(datetime).getTime();
var now = new Date().getTime();

if( isNaN(datetime) )
{
    return "";
}

console.log( datetime + " " + now);

if (datetime < now) {
    var milisec_diff = now - datetime;
}else{
    var milisec_diff = datetime - now;
}

var days = Math.floor(milisec_diff / 1000 / 60 / (60 * 24));

var date_diff = new Date( milisec_diff );

return days + "d "+ (date_diff.getHours() - 5) + "h " + (date_diff.getMinutes() - 30) + "m";
}
0
задан CodeGeek123 17 January 2019 в 10:49
поделиться

2 ответа

Я нашел обходной путь для этого, используя функцию to_utc_timestamp в pyspark, однако не совсем уверен, является ли это наиболее эффективным, хотя, похоже, он отлично работает на примерно 100 млн строк данных. Вы можете избежать regex_replace, если ваша строка метки времени выглядела так - 1997-02-28 10: 30: 40.897748

 from pyspark.sql.functions import regexp_replace, to_utc_timestamp

 df = spark.createDataFrame([('19970228-10:30:40.897748',)], ['new_t'])
 df = df.withColumn('t', regexp_replace('new_t', '^(.{4})(.{2})(.{2})-', '$1-$2-$3 '))
 df = df.withColumn("time", to_utc_timestamp(df.t, "UTC").alias('t'))
 df.show(5,False)
 print(df.dtypes)
0
ответ дан CodeGeek123 17 January 2019 в 10:49
поделиться

Обычно гранулярность меток времени указывается в секундах, поэтому я не думаю, что существует прямой метод сохранения гранулярности в миллисекундах.

В pyspark есть функция unix_timestamp, которая:

unix_timestamp(timestamp=None, format='yyyy-MM-dd HH:mm:ss')

Конвертировать строку времени с данным шаблоном ('yyyy-MM-dd HH:mm:ss' по умолчанию) в метку времени Unix ( в секундах ), используя часовой пояс по умолчанию и локаль по умолчанию, возвращают ноль в случае неудачи.

if `timestamp` is None, then it returns current timestamp.

>>> spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles")
>>> time_df = spark.createDataFrame([('2015-04-08',)], ['dt'])
>>> time_df.select(unix_timestamp('dt', 'yyyy-MM-dd').alias('unix_time')).collect()
[Row(unix_time=1428476400)]
>>> spark.conf.unset("spark.sql.session.timeZone")

Пример использования:

import pyspark.sql.functions as F
res = df.withColumn(colName,  F.unix_timestamp(F.col(colName), \
    format='yyyy-MM-dd HH:mm:ss.000').alias(colName) )

Что вы можете сделать, это разделить строку даты (str.rsplit('.', 1)), разделяя миллисекунды (например, создавая другой столбец) в ваш фрейм данных.

РЕДАКТИРОВАТЬ

В вашем примере проблема в том, что время имеет тип string. Сначала вам нужно преобразовать его в тип timestamp: это можно сделать с помощью:

res = time_df.withColumn("new_col", to_timestamp("dt", "yyyyMMdd-hh:mm:ss"))

Затем вы можете использовать unix_timestap

res2 = res.withColumn("time",  F.unix_timestamp(F.col("parsed"), format='yyyyMMdd-hh:mm:ss.000').alias("time"))

Наконец, чтобы создать столбцы с миллисекунды:

res3 = res2.withColumn("ms", F.split(res2['dt'], '[.]').getItem(1))
0
ответ дан Francesco Boi 17 January 2019 в 10:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: