You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Parquet按行分块添加dummy列后,Snappy压缩能否缩减额外数据?

问题

我正在处理一个含1亿行的DataFrame,希望将其划分为100个各含100万行的Parquet文件,无需按特定列值分区,仅需按行分块。

已知可通过添加“dummy列”并传入partition_cols参数实现,代码如下:

data_size = len(data)
partition_size = 1_000_000
n_partitions, remainder = divmod(data_size, partition_size)
data["partition_id"] = np.concatenate([
    np.repeat(list(range(n_partitions)), partition_size),
    np.repeat(n_partitions + 1, remainder),
])
data.to_parquet("out", partition_cols=["partition_id"])

但我担心写入额外1亿个64位整数会造成浪费。Parquet通常采用Snappy等压缩算法,而该列是长重复整数序列,理论上压缩效果极佳。不过我不清楚Parquet文件格式与底层Arrow数组格式和压缩算法的交互,想了解使用Snappy时,这些额外整数是否会被压缩到极少字节,还是会显著增加数据集体积?

回答

首先可以明确:这种重复序列的dummy列用Snappy压缩后,几乎不会增加额外的存储体积,完全不用担心浪费问题。

原因可以从Parquet+Arrow的存储逻辑和Snappy的特性两方面拆解:

  • Arrow数组的编码优化:Arrow会先对这种高度重复的整数序列做字典编码(Dictionary Encoding)——把重复的整数(比如0到100)作为字典键,然后用对应的索引值替代原数据。原本1亿个64位整数,会被转换成101个唯一键(0到100)加上1亿个极小的索引值(比如只用1字节就能存下0-100的索引),这一步已经把数据量大幅压缩。
  • Snappy的二次压缩:Snappy针对重复/冗余数据的压缩效率极高,经过字典编码后的索引序列是连续重复的块(100万个0,接着100万个1,以此类推),Snappy能把这类序列压缩到极致,最终这个dummy列的实际存储大小可能只有几KB级别,相比1亿行的原始DataFrame可以忽略不计。

另外,还有个更直接的替代方案可以完全避免添加dummy列:直接按行切片写入,逻辑更直接且无额外存储开销,适合单纯按行分块的场景:

partition_size = 1_000_000
for i in range(0, len(data), partition_size):
    chunk = data.iloc[i:i+partition_size]
    chunk.to_parquet(f"out/part_{i//partition_size}.parquet")

内容的提问来源于stack exchange,提问作者shadowtalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:50:30