【问题标题】:getting inconsistent behaviour when passing timestamp between spark and pandas在 spark 和 pandas 之间传递时间戳时出现不一致的行为
【发布时间】:2021-07-25 02:19:55
【问题描述】:

我正在尝试在 spark 和 pandas 之间共享数据帧,但在处理时间戳时遇到了奇怪的行为(对于在非配置 UTC 中生成的时间戳)

给定一个同时具有时间戳顶级字段和嵌套字段中的时间戳的数据帧,它们将被区别对待

df1.show(vertical=True, truncate=False)
-RECORD 0---------------------------
 id  | 1                            
 ts1 | 2021-05-02 04:21:15.918449   
 ts2 | {2021-05-02 04:21:15.918449} 
-RECORD 1---------------------------
 id  | 2                            
 ts1 | 2021-05-02 04:21:15.918449   
 ts2 | {2021-05-02 04:21:15.918449} 
-RECORD 2---------------------------
 id  | 3                            
 ts1 | 2021-05-02 04:21:15.918449   
 ts2 | {2021-05-02 04:21:15.918449} 

df1.toPandas()
    id  ts1 ts2
0   1   2021-05-02 04:23:36.438987  (2021-05-02 11:23:36.438987,)
1   2   2021-05-02 04:23:36.438987  (2021-05-02 11:23:36.438987,)
2   3   2021-05-02 04:23:36.438987  (2021-05-02 11:23:36.438987,)

在顶级字段中,时间戳显示为本地时间,在嵌套字段中显示为 UTC。

当试图将数据帧保存到 parquet 并从 pandas 中读取时,结果发生了更多变化,嵌套值被转换为 int(从 epoch 开始的纳秒),并且顶层值保持原样。

带有可运行示例的笔记本: https://colab.research.google.com/drive/1QWivTFHR7SS91pVBvCAbpJ3lYWgw0Nk1?usp=sharing

知道不一致的根源是什么吗?

编辑

更多数据

数据框的架构:

root
 |-- id: integer (nullable = true)
 |-- ts1: timestamp (nullable = false)
 |-- ts2: struct (nullable = false)
 |    |-- col1: timestamp (nullable = false)

df1.head()

Row(id=1, ts1=datetime.datetime(2021, 5, 2, 12, 3, 25, 809113), ts2=Row(col1=datetime.datetime(2021, 5, 2, 12, 3, 25, 809113)))

【问题讨论】:

    标签: pandas apache-spark parquet apache-arrow


    【解决方案1】:

    我相信不一致的根源是结构的表示,它是一个包含 Python 日期时间对象的 Spark Row 对象。因此,在 pandas 数据框中,ts1 列具有 pandas 日期时间类型,而 ts2 列具有 Spark Row 类型(您可以通过选择 df1.toPandas().t2[0] 来确认这一点)。

    Spark Row 类型的问题在于它使用 Python datetime 对象,该对象遵循 Python 时区而不是 Spark Session 时区。 Spark 可能太聪明了,没有意识到这一点,因此在从数据帧到 Row 对象的转换过程中,它会考虑 Spark Session 时区和 Python 时区之间的差异,从而给出您观察到的差异。

    要解决此问题,您可以在调用.toPandas() 之前将 Python 时区设置如下:

    import os
    import time
    
    os.environ['TZ'] = 'America/Los_Angeles'
    time.tzset()
    

    【讨论】:

    • 设置 python 时区确实有帮助,但类型相同 - 为问题添加了详细信息
    • 时间戳不同于行(时间戳)。行/结构可以包含许多不同的字段,并以不同的方式处理
    猜你喜欢
    • 1970-01-01
    • 2014-02-22
    • 2012-10-30
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 2020-06-16
    • 2014-04-14
    相关资源
    最近更新 更多