将时间戳转换为 Spark 数据帧中的日期



我已经看到了(在这里:如何在数据帧中将时间戳转换为日期格式?)在日期类型中转换时间戳的方法,但是,至少对我来说,它不起作用。

这是我尝试过的:

# Create dataframe
df_test = spark.createDataFrame([('20170809',), ('20171007',)], ['date',])
# Convert to timestamp
df_test2 = df_test.withColumn('timestamp',func.when((df_test.date.isNull() | (df_test.date == '')) , '0')
.otherwise(func.unix_timestamp(df_test.date,'yyyyMMdd')))
# Convert timestamp to date again
df_test2.withColumn('date_again', df_test2['timestamp'].cast(stypes.DateType())).show()

但这在列中返回 nulldate_again

+--------+----------+----------+
|    date| timestamp|date_again|
+--------+----------+----------+
|20170809|1502229600|      null|
|20171007|1507327200|      null|
+--------+----------+----------+

知道什么是失败的吗?

以下内容:

func.when((df_test.date.isNull() | (df_test.date == '')) , '0')
.otherwise(func.unix_timestamp(df_test.date,'yyyyMMdd'))

不起作用,因为它的类型不一致 - 第一个子句返回string而第二个子句返回bigint。因此,如果dataNOT NULL而不是为空,它将始终返回NULL

它也已过时 - SQL 函数NULL且格式错误是安全的。无需进行额外检查。

In [1]: spark.sql("SELECT unix_timestamp(NULL, 'yyyyMMdd')").show()
+----------------------------------------------+
|unix_timestamp(CAST(NULL AS STRING), yyyyMMdd)|
+----------------------------------------------+
|                                          null|
+----------------------------------------------+

In [2]: spark.sql("SELECT unix_timestamp('', 'yyyyMMdd')").show()
+--------------------------+
|unix_timestamp(, yyyyMMdd)|
+--------------------------+
|                      null|
+--------------------------+

而且你不需要 Spark 2.2 或更高版本中的中间步骤:

from pyspark.sql.functions import to_date
to_date("date", "yyyyMMdd")

你应该执行以下操作

>>> df_test2.withColumn('date_again', func.from_unixtime('timestamp').cast(DateType())).show()
+--------+----------+----------+
|    date| timestamp|date_again|
+--------+----------+----------+
|20170809|1502216100|2017-08-09|
|20171007|1507313700|2017-10-07|
+--------+----------+----------+

和架构是

>>> df_test2.withColumn('date_again', func.from_unixtime('timestamp').cast(DateType())).printSchema()
root
|-- date: string (nullable = true)
|-- timestamp: string (nullable = true)
|-- date_again: date (nullable = true)

对于 pyspark:

假设您有一个字段名称:"日期时间">,它将日期显示为日期和时间

df添加一个显示"仅限日期">列的新字段,如下所示:

from pyspark.sql.functions  import date_format
df.withColumn("DateOnly", date_format('DateTime', "yyyyMMdd")).show()

这将在df中显示一个名为DateOnly- 日期为yyyymmdd形式的新列

要将 pyspark 数据帧 (df) 中的unix_timestamp列(称为TIMESTMP) 转换为Date类型:

下面是一个两步过程(可能有更短的方法):

  • 从 UNIX 时间戳转换为timestamp
  • timestamp转换为Date

最初df.printShchema()显示:-- TIMESTMP: long (nullable = true)

使用spark.SQL实现转换,如下所示:

df.registerTempTable("dfTbl")
dfNew= spark.sql("""
SELECT *, cast(TIMESTMP as Timestamp) as newTIMESTMP 
FROM dfTbl d
""")
dfNew.printSchema()

printSchema() 将显示:

-- newTIMESTMP: timestamp (nullable = true)

最后将类型从timestamp转换为Date,如下所示:

from pyspark.sql.types import DateType
dfNew=dfNew.withColumn('actual_date', dfNew['newTIMESTMP'].cast(DateType()))
#udf to convert the ts to timestamp
get_timestamp = udf(lambda x : datetime.datetime.fromtimestamp(x/ 1000.0).strftime("%Y-%m-%d %H:%M:%S"))
#apply this udf in the dataframe with your timestamp
df_withdate = df.withColumn("datetime", get_timestamp(df.ts))

他们关闭了我的问题,因为我的问题与这个问题重复,所以我将我的答案复制并粘贴在这里(是重复的,对吧?

由于时间戳列以毫秒为单位,因此只需要转换为秒并将其转换为TimestampType,这应该可以解决问题:

from pyspark.sql.types import TimestampType
import pyspark.sql.functions as F
df.select( 
(F.col("my_timestamp") / 1000).cast(TimestampType())
)

一个不带import TimestampType的选项:

import pyspark.sql.functions as F
F.from_unixtime(F.col('date_col') / 1000).cast('date')

您可以直接投射字段:

df = df.withColumn('datetime', col('timestamp').cast(TimestampType()))

相关内容

  • 没有找到相关文章

最新更新