我有Spark数据帧,其中时间戳以毫秒为单位。
+-----------------------+
|CALC_TS |
+-----------------------+
|2021-01-27 01:35:05.043|
|2021-01-27 01:35:05.043|
|2021-01-27 01:35:05.043|
我想让它像这样显示微秒:
+--------------------------+
|CALC_TS |
+--------------------------+
|2021-01-27 01:35:05.043000|
|2021-01-27 01:35:05.043000|
|2021-01-27 01:35:05.043000|
所以基本上我希望毫秒部分以微秒的形式显示。在上面的例子中,来自第一个数据帧的43
毫秒将是43 thousand
微秒,如秒数据帧所示。
I have try:
df.withColumn('TIME', to_timestamp('CALC_TS', 'yyyy-MM-dd HH:mm:ss.SSSSSS'))
和
df.withColumn('TIME', col('CALC_TS').cast("timestamp"))
但是它们给出了相同的结果并且去掉了最后3个0。有办法做到这一点吗?
to_timestamp(timestamp_str[,fmt])
接受一个字符串并返回一个时间戳(类型)。如果您的CALC_TS
已经是一个时间戳,那么您应该使用df.withColumn('TIME', date_format('CALC_TS','yyyy-MM-dd HH:mm:ss.SSSSSS'))
将其格式化为字符串,具有微秒精度。来自Spark参考:
o分数:使用一个或多个(最多9个)连续的'S'字符,例如SSSSSS,用于解析和格式化秒的一小部分。对于解析,可接受的分数长度为[1,连续' S '的个数]。对于格式化,分数长度将被填充为数字Spark支持毫秒级的datetime精度,最多有6位有效数字,但可以解析纳秒,超过部分截断。
对于Spark 2.4,只是为了使看起来像时间戳字段的精度是微秒,也许你可以"伪造"。像这样格式化:date_format('CALC_TS','yyyy-MM-dd HH:mm:ss.SSS000')
您可以使用rpad。
右pad,末尾为零,直到时间戳的预期长度。在您的示例中,长度为26个字符(用于格式yyyy-MM-dd HH:mm:ss.SSSSSS
)
from pyspark.sql.functions import *
df.withColumn('CALC_TS_1', col('CALC_TS').cast("timestamp"))
.withColumn('CALC_TS_1', rpad(col('CALC_TS_1').cast('string'),26,'0'))
.show(truncate=False)
+--------------------------+--------------------------+
|CALC_TS |CALC_TS_1 |
+--------------------------+--------------------------+
|2021-01-27 01:35:05.043 |2021-01-27 01:35:05.043000|
|2021-01-27 01:35:05.043567|2021-01-27 01:35:05.043567|
+--------------------------+--------------------------+
如果列CALC_TS
是字符串类型,首先使用to_timestamp
和unix_timestamp
函数转换为TimestampType
,然后使用date_format
,您可以将其格式化为以毫秒为单位的6分数:
from pyspark.sql import functions as F
df.printSchema()
#root
# |-- CALC_TS: string (nullable = true)
df1 = df.withColumn(
'TIME',
F.to_timestamp(
F.unix_timestamp('CALC_TS', "yyyy-MM-dd HH:mm:ss.SSS") # seconds
+ F.substring_index('CALC_TS', '.', -1).cast('float') / 1000 # milliseconds part
)
).withColumn(
"TIME_FORMAT",
F.date_format("TIME", "yyyy-MM-dd HH:mm:ss.SSSSSS")
)
df1.show(truncate=False)
#+-----------------------+-----------------------+--------------------------+
#|CALC_TS |TIME |TIME_FORMAT |
#+-----------------------+-----------------------+--------------------------+
#|2021-01-27 01:35:05.043|2021-01-27 01:35:05.043|2021-01-27 01:35:05.000043|
#|2021-01-27 01:35:05.043|2021-01-27 01:35:05.043|2021-01-27 01:35:05.000043|
#|2021-01-27 01:35:05.043|2021-01-27 01:35:05.043|2021-01-27 01:35:05.000043|
#+-----------------------+-----------------------+--------------------------+
#root
# |-- CALC_TS: string (nullable = true)
# |-- TIME: timestamp (nullable = true)
# |-- TIME_FORMAT: string (nullable = true)
如果列已经是时间戳类型,只需像上面的代码一样使用date_format
。