Python 在PySpark中使用微秒时间戳

Python 在PySpark中使用微秒时间戳,python,scala,apache-spark,pyspark,apache-spark-sql,Python,Scala,Apache Spark,Pyspark,Apache Spark Sql,我有一个pyspark数据帧,其时间格式如下20190111-08:15:45.275753。我想将其转换为时间戳格式,保持微秒级的粒度。然而,似乎很难保持微秒,因为pyspark中的所有时间转换都会产生秒 你知道怎么做吗?请注意,将其转换为熊猫等将不会工作,因为数据集是巨大的,所以我需要一个有效的方法来做到这一点。下面是我如何做到这一点的示例 time_df = spark.createDataFrame([('20150408-01:12:04.275753',)], ['dt']) res

我有一个pyspark数据帧,其时间格式如下
20190111-08:15:45.275753
。我想将其转换为时间戳格式,保持微秒级的粒度。然而,似乎很难保持微秒,因为pyspark中的所有时间转换都会产生秒

你知道怎么做吗?请注意,将其转换为熊猫等将不会工作,因为数据集是巨大的,所以我需要一个有效的方法来做到这一点。下面是我如何做到这一点的示例

time_df = spark.createDataFrame([('20150408-01:12:04.275753',)], ['dt'])
res = time_df.withColumn("time",  unix_timestamp(col("dt"), \
format='yyyyMMdd-HH:mm:ss.000').alias("time"))
res.show(5, False)

通常时间戳粒度是以秒为单位的,所以我认为没有直接的方法来保持毫秒粒度

pyspark中有一个函数
unix\u timestamp

unix\u时间戳(timestamp=None,format='yyyy-MM-dd HH:MM:ss')

使用给定模式转换时间字符串(
'yyyy-MM-dd HH:MM:ss'
,默认情况下) 使用默认时区和默认 区域设置,如果失败则返回null

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。首先,您需要将其转换为
时间戳
类型:这可以通过以下方式完成:

res = time_df.withColumn("new_col", to_timestamp("dt", "yyyyMMdd-hh:mm:ss"))
然后可以使用
unix\u时间戳

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))

我已经在pyspark中找到了一个解决方法,使用to_utc_timestamp函数可以解决这个问题,但是不完全确定这是否是最有效的,尽管它似乎可以处理大约1亿行数据。如果时间戳字符串如下所示,则可以避免使用regex_替换- 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)

时间戳是否类似于
20190111-08:15.45.275753
2019-01-11-08:15.45.275753
?不幸的是,这不适用于我。字段上的值为空。您是否更改了格式以使其适合您的列?是的,我使用-yyyyMMdd HH:mm:ss.000,我的时间如下:20190104-01:12:04.275753您是否可以发布代码以使用相同的架构创建数据框?我已更新了帖子描述以包含此详细信息