在Pyspark中将时间戳更改为UTC格式

时间:2017-08-01 09:50:08

标签: apache-spark pyspark spark-dataframe

我有输入数据框( ip_df ),此数据框中的数据如下所示:

id            timestamp_value
1       2017-08-01T14:30:00+05:30
2       2017-08-01T14:30:00+06:30
3       2017-08-01T14:30:00+07:30

我需要创建一个新的数据帧( op_df ),其中我需要将timestamp值转换为UTC格式。所以最终输出数据框如下所示:

id            timestamp_value
1       2017-08-01T09:00:00+00:00
2       2017-08-01T08:00:00+00:00
3       2017-08-01T07:00:00+00:00

我想用PySpark实现它。有人可以帮我吗?任何帮助都将得到帮助。

2 个答案:

答案 0 :(得分:4)

如果你绝对需要按照指示完全格式化时间戳,即时区表示为“+00:00”,我认为使用UDF作为already suggested是你最好的选择。

但是,如果您可以容忍稍微不同的时区表示,例如无论是“+0000”(无冒号分隔符)还是“Z”,都可以在没有UDF的情况下执行此操作,根据数据集的大小,UDF可能会对您有更好的效果。

给出以下数据表示

+---+-------------------------+
|id |timestamp_value          |
+---+-------------------------+
|1  |2017-08-01T14:30:00+05:30|
|2  |2017-08-01T14:30:00+06:30|
|3  |2017-08-01T14:30:00+07:30|
+---+-------------------------+

由下列人员给出:

l = [(1, '2017-08-01T14:30:00+05:30'), (2, '2017-08-01T14:30:00+06:30'), (3, '2017-08-01T14:30:00+07:30')]
ip_df = spark.createDataFrame(l, ['id', 'timestamp_value'])

其中timestamp_valueString,您可以执行以下操作(这使用Spark 2.2中引入的to_timestampsession local timezone support):

from pyspark.sql.functions import to_timestamp, date_format
spark.conf.set('spark.sql.session.timeZone', 'UTC')
op_df = ip_df.select(
    date_format(
        to_timestamp(ip_df.timestamp_value, "yyyy-MM-dd'T'HH:mm:ssXXX"), 
        "yyyy-MM-dd'T'HH:mm:ssZ"
    ).alias('timestamp_value'))

产生:

+------------------------+
|timestamp_value         |
+------------------------+
|2017-08-01T09:00:00+0000|
|2017-08-01T08:00:00+0000|
|2017-08-01T07:00:00+0000|
+------------------------+

或略有不同:

op_df = ip_df.select(
    date_format(
        to_timestamp(ip_df.timestamp_value, "yyyy-MM-dd'T'HH:mm:ssXXX"), 
        "yyyy-MM-dd'T'HH:mm:ssXXX"
    ).alias('timestamp_value'))

产生:

+--------------------+
|timestamp_value     |
+--------------------+
|2017-08-01T09:00:00Z|
|2017-08-01T08:00:00Z|
|2017-08-01T07:00:00Z|
+--------------------+

答案 1 :(得分:1)

您可以在dateutil库中使用parser和tz。 我假设你有字符串,你想要一个字符串列: 来自dateutil导入解析器,tz 从pyspark.sql.types导入StringType 来自pyspark.sql.functions import col,udf #创建UTC时区 utc_zone = tz.gettz(' UTC') #创建应用于列的UDF函数 #它接受String,将其解析为时间戳,转换为UTC,然后再次转换为String func = udf(lambda x:parser.parse(x).astimezone(utc_zone).isoformat(),StringType()) #在数据集中创建新列 df = df.withColumn(" new_timestamp",func(col(" timestamp_value"))) 它给出了这个结果: <预> + - + ------------------------- + ------------------- ------ + | id | timestamp_value | new_timestamp | + - + ------------------------- + ------------------- ------ + | 1 | 2017-08-01T14:30:00 + 05:30 | 2017-08-01T09:00:00 + 00:00 | | 2 | 2017-08-01T14:30:00 + 06:30 | 2017-08-01T08:00:00 + 00:00 | | 3 | 2017-08-01T14:30:00 + 07:30 | 2017-08-01T07:00:00 + 00:00 | + - + ------------------------- + ------------------- ------ + < /预> 最后你可以删除并重命名: df = df.drop(" timestamp_value")。withColumnRenamed(" new_timestamp"," timestamp_value")