在 Parquet 中使用 Dask 日期/时间戳列存储

问题描述

我有一个 dask 数据框,它有两列,一个日期和一个值。

我是这样存储的:

ddf.to_parquet('/some/folder',engine='pyarrow',overwrite=True)

我希望 dask 将日期列存储为 Parquet 中的日期,但是当我使用 Apache Drill 查询它时,我得到 16 位数字(我会说是时间戳)而不是日期。例如我得到:

1546300800000000 而不是 2019-01-01

1548979200000000 而不是 2019-02-01

有没有办法告诉 dask 将列存储为日期?如何使用 Apache Drill 运行选择并获取日期?我尝试在 Drill 中使用 SELECT CAST,但它不会将数字转换为日期。

解决方法

不确定是否与您相关,但您似乎只对日期值感兴趣(忽略小时、分钟等)。如果是这样,您可以使用 .dt.date 将时间戳信息显式转换为日期字符串。

import pandas as pd
import dask.dataframe as dd

sample_dates = [
    '2019-01-01 00:01:00','2019-01-02 05:04:02','2019-01-02 15:04:02'
]

df = pd.DataFrame(zip(sample_dates,range(len(sample_dates))),columns=['datestring','value'])

ddf = dd.from_pandas(df,npartitions=2)

# convert to timestamp and calculate as unix time (relative to 1970)
ddf['unix_timestamp_seconds'] = (ddf['datestring'].astype('M8[s]') - pd.to_datetime('1970-01-01')).dt.total_seconds()

# convert to timestamp format and extract dates
ddf['datestring'] = ddf['datestring'].astype('M8[s]').dt.date

ddf.to_parquet('test.parquet',engine='pyarrow',write_index=False,coerce_timestamps='ms')

对于时间转换,您可以使用 .astypedd.to_datetime,请参阅 this question 的答案。还有一个非常相似的 questionanswer,这表明确保将时间戳向下转换为 ms 可以解决问题。

因此,使用您提供的值可以看到核心问题是变量缩放不匹配:

# both yield: Timestamp('2019-01-01 00:00:00')

pd.to_datetime(1546300800000000*1000,unit='ns')
pd.to_datetime(1546300800000000/1000000,unit='s')
,

如果没记错的话,Drill 使用旧的非标准 INT96 时间戳,而 Parquet 从来不支持这种方式。 parquet timestamp 本质上是一个 UNIX 时间戳,作为 int64,并具有各种精度。 Drill 必须有一个函数来正确地转换它的内部格式。

我不是 Drill 方面的专家,但您似乎需要先将整数除以适当的 10 次幂,(请参阅 this answer)。这个语法可能是错误的,但可能会给你一个想法:

SELECT TO_TIMESTAMP((mycol as FLOAT) / 1000) FROM ...;
,

这是有关 TO_TIMESTAMP() 函数的 Drill 文档的链接。 (https://drill.apache.org/docs/data-type-conversion/#to_timestamp) 我认为 @mdurant 的做法是正确的。

我会尝试:

SELECT TO_TIMESTAMP(<date_col>) FROM ...

SELECT TO_TIMSTAMP((<date_col> / 1000)) FROM ...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...