Передача и запись паркета с питоном и пандами получили ошибку отметки времени
Я попытался 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 к основной операции паркет не изменил поведение.