Передача и запись паркета с питоном и пандами получили ошибку отметки времени

Я попытался concat() два файла паркета с пандами в Python .
Это может работать, но когда я пытаюсь записать и сохранить фрейм данных в файл паркета, он отображает ошибку:

 ArrowInvalid: Casting from timestamp[ns] to timestamp[ms] would lose data:

Я проверил док. из панд, это по умолчанию синтаксис метки времени в мс при записи файла паркета.
Как я могу побелить файл паркета использованной схемой после concat?
Вот мой код:

import pandas as pd

table1 = pd.read_parquet(path= ('path.parquet'),engine='pyarrow')
table2 = pd.read_parquet(path= ('path.parquet'),engine='pyarrow')

table = pd.concat([table1, table2], ignore_index=True) 
table.to_parquet('./file.gzip', compression='gzip')

0 ответов

Панды уже отправляют неизвестных kwargs в базовый паркетный двигатель, так как, по крайней мере, v0.22, Таким образом, используя table.to_parquet(allow_truncated_timestamps=True) должно работать - я проверил это для панд v0.25.0 и пиарроу 0.13.0, Для получения дополнительных ключевых слов см. Документы Pyarrow.

Спасибо @axel за ссылку на документацию Apache Arrow:

allow_truncated_timestamps (bool, по умолчанию False) - разрешить потерю данных при принуждении временных меток к определенному разрешению. Например, если микросекундные или наносекундные данные теряются при принуждении к "мс", не создавайте исключения.

Кажется, что в современных версиях Pandas мы можем передавать параметры в ParquetWriter.

Следующий код у меня работал правильно (Pandas 1.1.1, PyArrow 1.0.1):

df.to_parquet(filename, use_deprecated_int96_timestamps=True)

Я думаю, что это ошибка, и вы должны делать то, что говорит Уэс. Однако, если вам нужен рабочий код сейчас, у меня есть обходной путь.

Решение, которое работало для меня, состояло в том, чтобы указать столбцы меток времени с точностью до миллисекунды. Если вам нужна точность в наносекунду, это испортит ваши данные... но если это так, то это может быть наименьшей из ваших проблем.

import pandas as pd

table1 = pd.read_parquet(path=('path1.parquet'))
table2 = pd.read_parquet(path=('path2.parquet'))

table1["Date"] = table1["Date"].astype("datetime64[ms]")
table2["Date"] = table2["Date"].astype("datetime64[ms]")

table = pd.concat([table1, table2], ignore_index=True) 
table.to_parquet('./file.gzip', compression='gzip')

У меня возникла связанная с этим проблема порядка величины при написании dask DataFrames со столбцами datetime64[ns] в AWS S3 и их сканировании в таблицы Athena.

Проблема заключалась в том, что последующие запросы Athena показывали поля datetime как год>57000 вместо 2020 года. Мне удалось использовать следующее исправление:

df.to_parquet(path, times="int96")

Который пересылает kwarg **{"times": "int96"} в fastparquet.writer.write().

Полученный файл паркета я проверил с помощью пакета parquet-tools. Он действительно показывает столбцы datetime как формат хранения INT96. В Athena (который основан на Presto) формат int96 хорошо поддерживается и не имеет проблем с порядком величины.

Ссылка: https://github.com/dask/fastparquet/blob/master/fastparquet/writer.py, функция write(), кварг times. (dask 2.30.0; fastparquet 0.4.1; pandas 1.1.4)

Я столкнулся с подобной проблемой при использовании pd.to_parquetмой последний обходной путь должен был использовать аргумент engine='fastparquet', но я понимаю, что это не поможет, если вам нужно использовать PyArrow специально.

Вещи, которые я пробовал, которые не работали:

  • Обходной путь @DrDeadKnee для ручной колонки .astype("datetime64[ms]") не работал для меня (панды против 0.24.2)
  • Переходя coerce_timestamps='ms' как kwarg к основной операции паркет не изменил поведение.
Другие вопросы по тегам