【问题标题】:PySpark dataframe convert unusual string format to TimestampPySpark 数据帧将异常字符串格式转换为时间戳
【发布时间】:2016-08-22 20:47:06
【问题描述】:

我正在通过 Spark 1.5.0 使用 PySpark。 我在日期时间值的列的行中有一个不寻常的字符串格式。它看起来像这样:

Row[(datetime='2016_08_21 11_31_08')]

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

df = df.withColumn("date_time",df.datetime.astype('Timestamp'))

我曾认为像regexp_replace 这样的 Spark SQL 函数可以工作,但我当然需要替换 _- 在日期的一半 和_: 在时间部分。

我在想我可以使用 substring 将列分成 2 列,然后从时间的尽头倒数。然后分别执行“regexp_replace”,然后连接。但这似乎很多操作?有没有更简单的方法?

【问题讨论】:

    标签: apache-spark dataframe pyspark apache-spark-sql timestamp


    【解决方案1】:

    火花 >= 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|
    ## +-------------------+-------------------+
    

    火花

    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|
    ## +-------------------+---------------------+
    

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

    【讨论】:

    • 太棒了。详情可以查看issues.apache.org/jira/browse/SPARK-11724
    • 如果时间戳字符串有时区,我可以使用unix_timestamp 函数吗?也就是说,模式是yyyy_MM_dd HH_mm_ss z like 1995_05_20 20_30_11 -400?
    【解决方案2】:

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

    df.withColumn('datetime', col('datetime_str').cast('timestamp'))
    

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

    【讨论】:

      【解决方案3】:

      我从 Florent F's answer 添加了更多代码行,以便更好地理解和在本地机器上运行 sn-p:

      import os, pdb, sys
      import pyspark
      from pyspark.sql import SparkSession
      from pyspark.sql import Row
      from pyspark.sql.types import StructType, ArrayType  
      from pyspark.sql.types import StringType
      from pyspark.sql.functions import col
      
      sc = pyspark.SparkContext('local[*]')
      spark = SparkSession.builder.getOrCreate()
      
      # preparing some example data - df1 with String type and df2 with Timestamp type
      df1 = sc.parallelize([{"key":"a", "date":"2016-02-01"}, 
          {"key":"b", "date":"2016-02-02"}]).toDF()
      df1.show()
      
      df2 = df1.withColumn('datetime', col('date').cast("timestamp"))
      df2.show()
      

      【讨论】:

        【解决方案4】:

        我完全同意所选答案,但是我想将格式设置为“yyyy_MM_dd HH_mm_ss”,以避免出现像“2019_01_27 16_00_00”这样的时间戳出现问题 -> 注意小时 > 12

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-02
          • 2018-02-19
          • 2021-12-01
          • 2021-06-15
          • 2021-03-29
          相关资源
          最近更新 更多