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

为何Pandas用zstd压缩等级10生成的Parquet文件比Spark更小?

Pandas与Spark生成zstd压缩Parquet文件的体积差异原因分析

测试环境与现象

在Ubuntu的ext4原生文件系统环境下,使用Parquet格式并设置zstd压缩等级为10时,Pandas(基于pyarrow引擎)生成的文件体积远小于Apache Spark生成的文件。将Spark生成的Parquet文件通过Pandas加载后重新保存,体积差异显著。

Spark生成代码

df
  .coalesce(1)
  .write
    .option("compression", "zstd")
    .option("compressionLevel", "10")
    .mode("overwrite")
    .parquet(parquetPath)

Pandas重写代码

>>> import pandas as pd
>>> df = pd.read_parquet('results/data1.parquet')
>>> df.to_parquet('data1.parquet', engine='pyarrow', compression="zstd", compression_level=10, index=False)
>>> df = pd.read_parquet('results/data2.parquet')
>>> df.to_parquet('data2.parquet', engine='pyarrow', compression="zstd", compression_level=10, index=False)

体积对比统计

文件路径Apache Spark体积Pandas体积Pandas/Spark体积比
results/data1.parquet2377805321724424330.72
results/data2.parquet62052301419170630.67

软件版本信息

  • Apache Spark-4.0.0-preview1
  • scala-2.13.14
  • Java 21.0.4
  • python-3.12.4
  • pandas-2.2.3
  • pyarrow-19.0.1

补充元数据对比

初始文件列表

pqt$ ls -l
-r--r--r-- 1 user user 237780532 May 20 11:55 spark.parquet

元数据查看与重写操作

pqt$ python3
Python 3.12.4 | packaged by Anaconda, Inc. | (main, Jun 18 2024, 15:12:24) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyarrow.parquet as pq
>>> import pandas as pd
>>> df = pd.read_parquet('spark.parquet')
>>> df.to_parquet('pandas.parquet', engine='pyarrow', compression="zstd", compression_level=10, index=False)
>>> parquet_file = pq.ParquetFile('spark.parquet')
>>> print(parquet_file.metadata)
<pyarrow._parquet.FileMetaData object at 0x11e8091de2a0>
  created_by: parquet-mr version 1.13.1 (build db4183109d5b734ec5930d870cdae161e408ddba)
  num_columns: 3
  num_rows: 20000
  num_row_groups: 2
  format_version: 1.0
  serialized_size: 1001
>>> parquet_file = pq.ParquetFile('pandas.parquet')
>>> print(parquet_file.metadata)
<pyarrow._parquet.FileMetaData object at 0x11e808d57fb0>
  created_by: parquet-cpp-arrow version 19.0.1
  num_columns: 3
  num_rows: 20000
  num_row_groups: 1
  format_version: 2.6
  serialized_size: 1905
>>>

重写后文件列表与体积计算

pqt$ ls -l
-rw-rw-r-- 1 user user 172442433 May 20 12:01 pandas.parquet
-r--r--r-- 1 user user 237780532 May 20 11:55 spark.parquet

pqt$ bc
scale = 2
172442433 / 237780532
.72

差异原因分析

  1. Parquet格式版本与实现库差异
    • Spark依赖parquet-mr 1.13.1生成Parquet 1.0格式,而Pandas基于pyarrow(parquet-cpp-arrow 19.0.1)生成更晚的Parquet 2.6格式。新版本格式在存储布局、元数据编码等方面有优化,能提升压缩效率。
  2. Row Group数量差异
    • Spark生成的文件包含2个Row Group,Pandas生成的是1个Row Group。更大的Row Group意味着压缩时可处理的数据块规模更大,zstd这类算法在处理连续大数据块时能找到更多重复模式,进而获得更高压缩比。
  3. zstd实现细节差异
    • Spark的parquet-mr与pyarrow使用的zstd实现版本、参数调优逻辑可能存在差异,即使压缩等级同为10,实际压缩效果也会不同。
  4. 列存储编码策略差异
    • 作为列存格式,不同Parquet实现库在列数据编码方式、字典编码的使用策略上有区别。pyarrow可能采用了更高效的列编码方式,配合zstd压缩进一步降低文件体积。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:27:01