PySpark数据帧将异常字符串格式转换为Timestamp

PR1*_*012 23 timestamp dataframe apache-spark apache-spark-sql pyspark

我通过Spark 1.5.0使用PySpark.对于datetime值,我在列的行中有一个不常见的String格式.它看起来像这样:

Row[(daytetime='2016_08_21 11_31_08')]
Run Code Online (Sandbox Code Playgroud)

有没有办法将这种非正统yyyy_mm_dd hh_mm_dd格式转换为时间戳?最终可能出现的问题

df = df.withColumn("date_time",df.daytetime.astype('Timestamp'))
Run Code Online (Sandbox Code Playgroud)

我原以为像星火SQL函数regexp_replace可以工作,但我当然需要更换 _-在日期一半_:在部分时间.

我想我可以在2中拆分列,substring并从时间结束后向后计数.然后单独执行'regexp_replace',然后连接.但这似乎很多操作?有没有更简单的方法?

zer*_*323 43

Spark> = 2.2

from pyspark.sql.functions import to_timestamp

(sc
    .parallelize([Row(dt='2016_08_21 11_31_08')])
    .toDF()
    .withColumn("parsed", to_timestamp("dt", "yyyy_MM_dd HH_mm_ss"))
    .show(1, False))

## +-------------------+-------------------+
## |dt                 |parsed             |
## +-------------------+-------------------+
## |2016_08_21 11_31_08|2016-08-21 11:31:08|
## +-------------------+-------------------+
Run Code Online (Sandbox Code Playgroud)

Spark <2.2

没有什么是unix_timestamp无法处理的:

from pyspark.sql import Row
from pyspark.sql.functions import unix_timestamp

(sc
    .parallelize([Row(dt='2016_08_21 11_31_08')])
    .toDF()
    .withColumn("parsed", unix_timestamp("dt", "yyyy_MM_dd HH_mm_ss")
    # For Spark <= 1.5
    # See issues.apache.org/jira/browse/SPARK-11724 
    .cast("double")
    .cast("timestamp"))
    .show(1, False))

## +-------------------+---------------------+
## |dt                 |parsed               |
## +-------------------+---------------------+
## |2016_08_21 11_31_08|2016-08-21 11:31:08.0|
## +-------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,格式字符串应与Java兼容SimpleDateFormat.


Flo*_*t F 9

zero323的答案回答了这个问题,但我想补充一点,如果您的datetime字符串具有标准格式,则应该可以将其直接转换为时间戳类型:

df.withColumn('datetime', col('datetime_str').cast('timestamp'))
Run Code Online (Sandbox Code Playgroud)

它具有处理毫秒的优势,而unix_timestamp仅具有秒精度(to_timestamp也可以使用毫秒,但需要Spark> = 2.2,如zero323所述)。我在Spark 2.3.0上使用以下格式对其进行了测试:'2016-07-13 14:33:53.979'(带毫秒,但没有它们也可以使用)。