使用 python 和 pandas 传输和写入 Parquet 时出现时间戳错误
Transfer and write Parquet with python and pandas got timestamp error
我试图在 python 中用 pandas concat() 两个镶木地板文件。
它可以工作,但是当我尝试写入数据框并将其保存到镶木地板文件时,它显示错误:
ArrowInvalid: Casting from timestamp[ns] to timestamp[ms] would lose data:
我查了文档。 of pandas,写入parquet文件时默认时间戳语法以毫秒为单位。
如何在 concat 后使用已用模式将 parquet 文件白色化?
这是我的代码:
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')
我认为这是一个错误,您应该按照 Wes 所说的进行操作。但是,如果您现在需要工作代码,我有一个解决方法。
对我有用的解决方案是将时间戳列指定为毫秒精度。如果您需要纳秒精度,这会破坏您的数据...但如果是这样,这可能是您的问题中最少的。
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')
我在使用 pd.to_parquet
时遇到了类似的问题,我最终的解决方法是使用参数 engine='fastparquet'
,但我意识到如果您需要专门使用 PyArrow,这并没有帮助。
我试过但没有用的东西:
- @DrDeadKnee 的手动转换列
.astype("datetime64[ms]")
的解决方法对我不起作用(pandas v. 0.24.2
)
- 将
coerce_timestamps='ms'
作为 kwarg 传递给底层 parquet 操作并没有改变行为。
Pandas 至少从 v0.22
开始就已经将未知的 kwargs 转发给底层的镶木地板引擎。因此,使用 table.to_parquet(allow_truncated_timestamps=True)
应该有效——我针对 pandas v0.25.0
和 pyarrow 0.13.0
验证了它。有关更多关键字,请参阅 the pyarrow docs。
感谢@axel link to Apache Arrow documentation:
allow_truncated_timestamps (bool, default False) – Allow loss of data when coercing timestamps to a particular resolution. E.g. if
microsecond or nanosecond data is lost when coercing to ‘ms’, do not
raise an exception.
似乎在现代 Pandas 版本中我们可以将参数传递给 ParquetWriter
。
以下代码对我来说工作正常(Pandas 1.1.1,PyArrow 1.0.1):
df.to_parquet(filename, use_deprecated_int96_timestamps=True)
我在将带有 datetime64[ns] 列的 dask DataFrame 写入 AWS S3 并将它们爬入 Athena 表时遇到了一个相关的数量级问题。
问题是后续的 Athena 查询将日期时间字段显示为年份 >57000 而不是 2020。我设法使用了以下修复:
df.to_parquet(path, times="int96")
将 kwarg **{"times": "int96"}
转发到 fastparquet.writer.write()。
我使用包 parquet-tools 检查了生成的 parquet 文件。它确实将日期时间列显示为 INT96 存储格式。在 Athena(基于 Presto)上,int96 格式得到很好的支持,不存在数量级问题。
参考:https://github.com/dask/fastparquet/blob/master/fastparquet/writer.py、函数 write()
、kwarg times
。
(dask 2.30.0 ; fastparquet 0.4.1 ; pandas 1.1.4)
我试图在 python 中用 pandas concat() 两个镶木地板文件。
它可以工作,但是当我尝试写入数据框并将其保存到镶木地板文件时,它显示错误:
ArrowInvalid: Casting from timestamp[ns] to timestamp[ms] would lose data:
我查了文档。 of pandas,写入parquet文件时默认时间戳语法以毫秒为单位。
如何在 concat 后使用已用模式将 parquet 文件白色化?
这是我的代码:
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')
我认为这是一个错误,您应该按照 Wes 所说的进行操作。但是,如果您现在需要工作代码,我有一个解决方法。
对我有用的解决方案是将时间戳列指定为毫秒精度。如果您需要纳秒精度,这会破坏您的数据...但如果是这样,这可能是您的问题中最少的。
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')
我在使用 pd.to_parquet
时遇到了类似的问题,我最终的解决方法是使用参数 engine='fastparquet'
,但我意识到如果您需要专门使用 PyArrow,这并没有帮助。
我试过但没有用的东西:
- @DrDeadKnee 的手动转换列
.astype("datetime64[ms]")
的解决方法对我不起作用(pandas v.0.24.2
) - 将
coerce_timestamps='ms'
作为 kwarg 传递给底层 parquet 操作并没有改变行为。
Pandas 至少从 v0.22
开始就已经将未知的 kwargs 转发给底层的镶木地板引擎。因此,使用 table.to_parquet(allow_truncated_timestamps=True)
应该有效——我针对 pandas v0.25.0
和 pyarrow 0.13.0
验证了它。有关更多关键字,请参阅 the pyarrow docs。
感谢@axel link to Apache Arrow documentation:
allow_truncated_timestamps (bool, default False) – Allow loss of data when coercing timestamps to a particular resolution. E.g. if microsecond or nanosecond data is lost when coercing to ‘ms’, do not raise an exception.
似乎在现代 Pandas 版本中我们可以将参数传递给 ParquetWriter
。
以下代码对我来说工作正常(Pandas 1.1.1,PyArrow 1.0.1):
df.to_parquet(filename, use_deprecated_int96_timestamps=True)
我在将带有 datetime64[ns] 列的 dask DataFrame 写入 AWS S3 并将它们爬入 Athena 表时遇到了一个相关的数量级问题。
问题是后续的 Athena 查询将日期时间字段显示为年份 >57000 而不是 2020。我设法使用了以下修复:
df.to_parquet(path, times="int96")
将 kwarg **{"times": "int96"}
转发到 fastparquet.writer.write()。
我使用包 parquet-tools 检查了生成的 parquet 文件。它确实将日期时间列显示为 INT96 存储格式。在 Athena(基于 Presto)上,int96 格式得到很好的支持,不存在数量级问题。
参考:https://github.com/dask/fastparquet/blob/master/fastparquet/writer.py、函数 write()
、kwarg times
。
(dask 2.30.0 ; fastparquet 0.4.1 ; pandas 1.1.4)