Parquet文件重写在Pandas / PyArrow中的大小稍大

ycl3bljg  于 2022-12-09  发布在  其他
关注(0)|答案(1)|浏览(153)

因此,我尝试将一个 parquet 文件读入内存,选择文件的块并将其上传到AWS S3 Bucket。我想编写健全性测试,以检查文件是否通过大小检查或MD5哈希检查在本地和云文件之间正确上传。
我注意到的一件事是,将一个文件读入内存,无论是bytes还是pd.DataFrame/Table,然后将同一个对象重新写入一个新文件,都会改变文件的大小,在我的例子中,与原始文件相比会增加文件的大小。

import pandas as pd
df = pd.read_parquet("data/example.parquet")

然后我简单地写:

from io import ByteIO
buffer = ByteIO()
df.to_parquet(buffer) # this can be done straight without BytesIO. I use it for clarity.
with open('copy.parquet', 'rb') as f:
    f.write(buffer.getvalue())

现在对这两个文件使用ls -l会给予不同的大小:

37089 Oct 28 16:57 data/example.parquet
37108 Dec  7 14:17 copy.parquet

有趣的是,我尝试使用一个工具,例如xxddiff配对使用,令我惊讶的是,二进制差异分散在整个文件中,所以我认为这并不局限于元数据的差异。使用panda将两个文件重新加载到内存中会得到相同的表。值得一提的是,parquet文件同时包含NanNat值。不幸的是,我不能共享该文件,但我可以用一个小样本来复制该行为。我也尝试使用Pyarrow '的文件阅读功能,导致相同的文件大小:

import pyarrow as pa
import pyarrow.parquet as pq
with open('data/example.parquet', 'rb') as f:
    buffer = pa.BufferReader(obj)
table = pq.read_table(buffer)
pq.write_table(table, 'copy.parquet')

我也试过在两个版本中打开compression='snappy',但它没有改变输出。
写回磁盘时是否遗漏了某些配置?

6gpjuf90

6gpjuf901#

Pandas使用pyarrow来读/写parquet,所以结果是一样的,这并不奇怪。我不确定使用缓冲区与直接保存文件相比有什么清晰度,所以我在下面的代码中省略了它。
如果不是panda,而是直接使用pyarrow,则会显示出主要的 meta数据差异,因为panda除了正常的箭头元数据外,还添加了自己的模式。
虽然你说这不是这里的情况,所以可能的原因是,这个文件是由另一个系统写的不同版本的pyarrow,如Michael Delgado提到的意见snappy压缩是默认打开。Snappy is not deterministic between systems
不跨库版本(甚至可能不跨体系结构)
这就解释了为什么你会在文件中看到不同。你可以尝试下面的代码,看看在同一台机器上,md5在文件之间是一样的,但是Pandas版本由于添加了 meta数据而更大。
目前,arrow s3编写器不检查完整性,但S3 API有这样的功能。我已经打开了一个issue,使其可以通过arrow访问。

import pandas as pd
import pyarrow as pa
import numpy as np
import pyarrow.parquet as pq

arr = pa.array(np.arange(100))
table = pa.Table.from_arrays([arr], names=["col1"])

pq.write_table(table, "original.parquet")

pd_copy = pd.read_parquet("original.parquet")
copy = pq.read_table("original.parquet")

pq.write_table(copy, "copy.parquet")
pd_copy.to_parquet("pd_copy.parquet")

$ md5sum original.parquet copy.parquet pd_copy.parquet                                                                                 
fb70a5b1ca65923fec01a54f85f17260  original.parquet
fb70a5b1ca65923fec01a54f85f17260  copy.parquet
dcb93cb89426a948e885befdbee204ff  pd_copy.parquet

1092 copy.parquet
1092 original.parquet
2174 pd_copy.parquet

相关问题