python - PySpark DataFrame 无法正确解析时间

标签 python apache-spark datetime pyspark apache-spark-sql

我有一个日期时间为字符串类型的 DataFrame,如下所示:

Row(Created Date=u'7/6/15 10:58', Closed Date=u'7/22/15 1:07)

我想将其转换为日期时间,所以我尝试这种方式。首先,我删除所有没有的行。

df = df.na.drop(subset=["Created Date"])
df = df.na.drop(subset=["Closed Date"])

然后我指定日期时间字符串的格式

func =  F.udf(lambda x: datetime.strptime(x, '%m/%d/%y %H:%M'), DateType())

然后我将函数应用到这两列

df = df.withColumn('Created Date', func(F.col('Created Date')))
df = df.withColumn('Closed Date', func(F.col('Closed Date')))

但是,当我查看我的 DataFrame 时,日期时间采用这种格式

Row(Created Date=datetime.date(2015, 7, 6), Closed Date=datetime.date(2015, 7, 22)

小时和秒似乎神秘地消失了。我是否错误地解析了日期时间,或者是其他原因?谢谢!

最佳答案

这里有两个问题。

  • 当您需要 TimestampType 时,您正在使用 DateType(这就是您得到意外结果的原因):

    from pyspark.sql.types import TimestampType
    
    df = sc.parallelize([
        (u'7/6/15 10:58', '7/22/15 1:07')
    ]).toDF(['Created Date', 'Closed Date'])
    
    as_timestamp = F.udf(
        lambda x: datetime.strptime(x, '%m/%d/%y %H:%M'), TimestampType()
    )
    
    df.select(
        as_timestamp("Created Date"), as_timestamp("Closed Date")
    ).show(1, False)
    
    +----------------------+---------------------+
    |<lambda>(Created Date)|<lambda>(Closed Date)|
    +----------------------+---------------------+
    |2015-07-06 10:58:00.0 |2015-07-22 01:07:00.0|
    +----------------------+---------------------+
    
  • 您正在使用 UDF,您可以在其中使用 native 函数(这会导致显着的性能损失):

    def native_as_timestamp(colname, format='MM/dd/yy HH:mm'):
        """
        https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
        """
        return F.unix_timestamp(
            colname, format
        ).cast(TimestampType()).alias(colname)
    
    df.select(
        native_as_timestamp('Created Date'), native_as_timestamp('Closed Date')
    ).show(1, False)
    
    +---------------------+---------------------+
    |Created Date         |Closed Date          |
    +---------------------+---------------------+
    |2015-07-06 10:58:00.0|2015-07-22 01:07:00.0|
    +---------------------+---------------------+
    

    在最新版本 (>= 2.2.0) 中,您可以将 unix_timestamp(...).cast(...) 替换为 to_timesatmap :

    df.select(
        F.to_timestamp('Created Date', 'MM/dd/yy HH:mm').alias('Created Date'),     
        F.to_timestamp('Closed Date', 'MM/dd/yy HH:mm').alias('Closed Date')
    ).show(1, False)
    

关于python - PySpark DataFrame 无法正确解析时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41080083/

相关文章:

python - 是否有任何 python 机器学习库可以返回线性 svm 的系数或几何边距?

python - 字符串列表中最常见的部分字符串匹配

hadoop - 在 yarn 上运行 Spark 机学习示例失败

html - Django 模板转换 datetime-local 格式

r - R 中日期的定制地板/天花板

ruby - 迭代字符串数组并执行正则表达式

Python 类变量增量高于迭代次数

python - 捕获屏幕并找到引用图像

python - 如何使用pyspark计算出现次数

hadoop - 如何使用 Spark 在 yarn 簇模式下将原木直接打印到控制台上