PyArrow 的时间戳数据问题

问题描述 投票:0回答:3

我正在尝试使用 pyarrow 将数据从 csv 加载到 parquet 文件中。我使用转换选项将数据类型设置为其正确的类型,然后使用 timestamp_parsers 选项来指示应如何解释时间戳数据:请参阅下面我的“csv”:

time,data
01-11-19 10:11:56.132,xxx

请参阅下面我的代码示例。

import pyarrow as pa
from pyarrow import csv
from pyarrow import parquet


convert_dict = {
    'time': pa.timestamp('us', None),
    'data': pa.string()
}

convert_options = csv.ConvertOptions(
    column_types=convert_dict
    , strings_can_be_null=True
    , quoted_strings_can_be_null=True
    , timestamp_parsers=['%d-%m-%y %H:%M:%S.%f']
)

table = csv.read_csv('test.csv', convert_options=convert_options)
print(table)
parquet.write_table(table, 'test.parquet')

基本上,pyarrow 不喜欢某些 strptime 值。具体来说,在这种情况下,它不喜欢“%f”,它代表秒的小数部分(https://www.geeksforgeeks.org/python-datetime-strptime-function/)。任何帮助让 pyarrow 完成我需要的事情将不胜感激。

需要明确的是,如果我将数据编辑为没有小数秒,然后从 timestamp_parsers 选项中删除“%f”,我就可以运行代码。但是我需要保持数据的完整性,所以这不是一个选择。对我来说,这似乎是 pyarrow 中的错误,或者我是个白痴,错过了一些明显的东西。打开这两个选项只是想知道它是什么。

pyarrow strptime apache-arrow
3个回答
2
投票
pyarrow 不支持

%f
,而且很可能不会,因为它是 Python 特定的标志。请参阅此处的讨论:https://issues.apache.org/jira/browse/ARROW-15883。 PR 当然总是受欢迎的!

作为一种解决方法,您可以首先将时间戳读取为字符串,然后通过切掉小数部分来处理它们,并将其作为 pa.duration 添加到已处理的时间戳中:

import pyarrow as pa
import pyarrow.compute as pc
ts = pa.array(["1970-01-01T00:00:59.123456789", "2000-02-29T23:23:23.999999999"], pa.string())
ts2 = pc.strptime(pc.utf8_slice_codeunits(ts, 0, 19), format="%Y-%m-%dT%H:%M:%S", unit="ns")
d = pc.utf8_slice_codeunits(ts, 20, 99).cast(pa.int64()).cast(pa.duration("ns"))
pc.add(ts2, d)

0
投票

所以我发现对于时间戳数据,您应该尝试使用默认解析器格式(ISO8601)的数据。例如,如果您使用 pyarrow 时间戳数据类型将 csv 数据转换为 parquet。只要有这种格式的 csv 数据即可:

无时区

YYYY-MM-DDTHH:MI:SS.FF6

有时区

YYYY-MM-DDTHH:MI:SS.FF6TZH:TZM

0
投票

@Rok 提到的解析问题很不幸。这是将 ISO 8601 格式的字符串转换为 pa.timestamp 的另一种解决方法,但效率不高,因为它是从 arrow -> python list -> arrow (在 Arrow 版本 13.0.0 上测试的):

from datetime import datetime, timezone
import pyarrow as pa

def pyarrow_string_to_ts(col):
  time_string_list = col.to_pylist()
  timestamps = [datetime.fromisoformat(x).astimezone(timezone.utc) for x in time_string_list]
  return pa.array(timestamps)

sample_data = [{'price': '10.2', 'date': '2023-09-25T00:00:00.000000-04:00'}, {'price': '9.7', 'date': '2023-09-26T00:00:00.000000-05:00'}]
table = pa.Table.from_pylist(sample_data)

table = table.set_column(table.schema.get_field_index("date"), "date", pyarrow_string_to_ts(table.column("date")))
© www.soinside.com 2019 - 2024. All rights reserved.