pyspark to_timestamp不包括毫秒

时间:2019-01-04 18:06:58

标签: apache-spark pyspark

我正在尝试将时间戳列设置为包含毫秒的格式,但未成功。如何格式化我的时间,使其看起来像这样-class Person1 { constructor(name) { this.name = name; console.log(new.target) // => // => [Class: Person1] } } function Person2(){ this.name='cc' console.log(new.target) // => [Function: Person2] }

我看了看文档并遵循SimpleDataTimeFormat,pyspark文档说2019-01-04 11:09:21.152函数正在使用它们。

这是我的数据框。

to_timestamp

我使用毫秒格式,但没有成功,如下所示

+--------------------------+
|updated_date              |
+--------------------------+
|2019-01-04 11:09:21.152815|
+--------------------------+

我希望>>> df.select('updated_date').withColumn("updated_date_col2", to_timestamp("updated_date", "YYYY-MM-dd HH:mm:ss:SSS")).show(1,False) +--------------------------+-------------------+ |updated_date |updated_date_col2 | +--------------------------+-------------------+ |2019-01-04 11:09:21.152815|2019-01-04 11:09:21| +--------------------------+-------------------+ 的格式为updated_date_col2

3 个答案:

答案 0 :(得分:3)

我认为您可以使用UDF和Python的标准datetime模块,如下所示。

import datetime
from pyspark.sql.functions import udf
from pyspark.sql.types import TimestampType

def _to_timestamp(s):
    return datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S.%f')

udf_to_timestamp = udf(_to_timestamp, TimestampType())

df.select('updated_date').withColumn("updated_date_col2", udf_to_timestamp("updated_date")).show(1,False)

答案 1 :(得分:0)

这不是to_timestamp的解决方案,但您可以轻松地将列保持为时间格式

以下代码是将数字毫秒转换为时间戳的示例之一。

from datetime import datetime

ms = datetime.now().timestamp() # ex) ms = 1547521021.83301
df = spark.createDataFrame([(1, ms)], ['obs', 'time'])
df = df.withColumn('time', df.time.cast("timestamp"))
df.show(1, False) 

+---+--------------------------+
|obs|time                      |
+---+--------------------------+
|1  |2019-01-15 12:15:49.565263|
+---+--------------------------+

如果您在JS中使用new Date().getTime()Date.now()或在Python中使用datetime.datetime.now().timestamp(),则可以得到一个数字毫秒。

答案 2 :(得分:0)

原因pyspark to_timestamp仅解析到几秒钟,而TimestampType可以保留毫秒。

以下解决方法可能会起作用:

如果时间戳记模式包含S,则调用UDF以获取要在表达式中使用的字符串'INTERVAL MILLISECONDS'

ts_pattern = "YYYY-MM-dd HH:mm:ss:SSS"
my_col_name = "time_with_ms"

# get the time till seconds
df = df.withColumn(my_col_name, to_timestamp(df["updated_date_col2"],ts_pattern))

# add milliseconds as inteval
if 'S' in timestamp_pattern:
   df = df.withColumn(my_col_name, df[my_col_name] + expr("INTERVAL 256 MILLISECONDS"))

要获取间隔256个错误,我们可以使用Java UDF:

df = df.withColumn(col_name, df[col_name] + expr(getIntervalStringUDF(df[my_col_name], ts_pattern)))

内部UDF:getIntervalStringUDF(字符串timeString,字符串模式)

  1. 使用SimpleDateFormat根据模式解析日期
  2. 使用模式“'INTERVAL'SSS'MILLISECONDS'”以字符串形式返回格式化日期
  3. 针对解析/格式异常返回“ INTERVAL 0 MILLISECONDS”