pandas的存储格式parquet介绍
前几天刚刚知道了一种新的文件格式类型,叫做parquet,这是一种很高效的数据存储格式,适合dataframe形式的数据。
之前我在进行dataframe数据存储时,最常用的选择是csv
格式(因为导出以后是一个文本文件,可以直接在终端查看),后来了解到pickle格式以后,这种格式也成为了我的一个选择。其读写速度更快,且配合pandas
的compression
参数,可以实现很高的压缩比,能够节约许多磁盘空间。
1 | ## 导出data_df为pickle文件,启用lzma压缩 |
但parquet似乎是一种更高效的存储格式。下面是DeepSeek对这种格式的介绍:
DeepSeek-R1的介绍
User:
在保存python pandas的dataframe对象时,有多种格式可以选择,包括csv, excel, json, sql, pickle, parquet, feather等,请问这些格式的定义分别是什么?它们的存储效率,或者说对磁盘空间的利用率如何?如果我想最大限度利用我的磁盘空间,例如存储尽可能多数据,那么上述哪些格式会比较好,在存储这些数据时,compression
参数如何选择?
deepseek-r1:
嗯,用户现在在问关于Python pandas保存DataFrame时各种格式的区别,还有存储效率的问题,特别是如何最大化利用磁盘空间。我需要仔细理清楚每一种格式的定义和它们的存储效率,然后给出建议。
首先,我应该逐个回顾每种格式的定义。比如CSV是纯文本,逗号分隔;Excel是二进制表格格式;JSON是结构化的文本;SQL是存到数据库;Pickle是Python的序列化;Parquet和Feather是列式存储,针对大数据优化的 。然后存储效率方面,文本格式比如CSV、JSON通常占用空间大,而二进 制格式如Parquet、Feather、Pickle会更高效。尤其是列式存储格式,像Parquet和Feather,它们有压缩优势,特别是Parquet支持更好的压缩算 法,适合存储大量数据。
接下来要考虑用户的需求,他们希望最大限度利用磁盘空间,也就是存储尽可能多的数据,所以应该推荐压缩率高且高效的格式。这时候重点可能是Parquet和Feather,因为列式存储加上压缩通常体积更小。而Pickle虽然可能压缩率高,但兼容性和安全性可能有问题,可能不是最优选。同时,Parquet支持多种压缩算法比如Snappy、Gzip,而Gzip压缩率更高但读 写可能慢一点。用户可能需要根据情况选择压缩参数,比如compression=’gzip’来获得更高的压缩率。
然后考虑到用户可能在使用这些格式时需要注意的参数,比如在to_parquet的时候,compression参数设置为gzip或者snappy。snappy压缩和解压 速度快,但压缩率可能不如gzip。如果用户更在意空间,gzip更好。而Feather默认可能用lz4或者zstd,同样可以选择不同的压缩方式。另外,CSV或Excel如果必须用的话,可以启用压缩参数,例如gzip压缩的CSV,虽 然可能不如Parquet高效,但比普通文本节省空间。
可能还需要考虑其他因素,比如数据类型,Parquet对于嵌套数据的处理 更好,而Feather可能更适合临时存储,因为读写快。如果用户的数据量 极大,列式存储更合适。另外,是否需要跨平台兼容性,比如Parquet在Hadoop生态中更通用,而Feather可能更适合Python环境之间的快速交换。
需要提醒用户的是,不同格式的读写速度可能不同,但如果用户的首要目标是节省空间,那么高压缩率的列式存储格式是首选。同时,要检查pandas的API,确保在使用这些格式时正确设置compression参数,例如在to_parquet时指定compression=’gzip’,或者在to_csv时用compression=’gzip’等。此外,Parquet和Feather的压缩是否默认开启,需要确认,可能有些格式默认不压缩或者使用特定压缩算法。
总结的话,用户如果需要最大限度利用磁盘空间,应该优先选择Parquet (使用gzip或brotli压缩)或Feather(使用zstd压缩),因为这些格式 设计时就考虑了高效的存储和压缩。同时,调整compression参数到更高 压缩率的算法会更节省空间,尽管可能会稍微增加读写时间。
在保存Python pandas的DataFrame时,选择合适的格式和压缩方式可以显著影响存储效率和磁盘空间利用率。以下是各格式的定义、存储效率分析及优化建议:
1. 格式定义与存储效率对比
格式 | 定义 | 存储效率(空间利用率) |
---|---|---|
CSV | 纯文本,逗号分隔,人类可读 | 低效。文本冗余多,无压缩时体积大,但可 用压缩参数优化。 |
Excel | 二进制表格格式(如.xlsx 或.xls ),支持多表 和样式 |
较低效。二进制结构有一定优化,但不如列式存储格式高效。 |
JSON | 结构化文本格式,支持嵌套数据 | 低效。冗余键重复、文本无压缩,体积较大 。 |
SQL | 存储到关系型数据库(如SQLite、MySQL) | 中等。依赖数据库引擎的压缩和索引优化。 |
Pickle | Python序列化二进制格式,保留对象结构 | 较高。二进制紧凑,默认无压缩但支持压缩 参数优化。 |
Parquet | 列式存储格式(Apache生态),高效压缩,支持复杂数据类型 | 极高。列式存储+压缩算法大幅减少冗 余数据。 |
Feather | 列式存储格式(Arrow生态),设计用于快速读写 | 高。默认使用LZ4或ZSTD压缩,体积优于CSV但略逊于Parquet。 |
2. 最大化磁盘空间的推荐方案
(1) 最佳格式选择
首推 Parquet
列式存储天生适合压缩(尤其重复值和稀疏数据),支持多种压缩算法(如gzip
、snappy
、brotli
)。
优势:高压缩率,兼容大数据工具(Spark、Hive),支持分块存 储和谓词下推。
示例代码:1
df.to_parquet("data.parquet", compression="gzip") # 更高压缩 率选brotli
次选 Feather + ZSTD
读写速度极快,ZSTD压缩率接近Parquet,适合短期存储或Python生态 内交换数据。
示例代码:1
df.to_feather("data.feather", compression="zstd")
(2) 其他格式的优化建议
- CSV/JSON:启用压缩参数(如
compression="gzip"
),体积可缩小70%-90%。 - Pickle:使用
protocol=5
+compression="gzip"
(需Pandas 1.5+)。1
df.to_pickle("data.pkl", protocol=5, compression="gzip")
3. 压缩算法选择建议
- 追求极致压缩率:
选择gzip
(Parquet、CSV)或brotli
(Parquet)。压缩率高,但 解压稍慢。 - 平衡速度与压缩率:
选择zstd
(Feather、Parquet)或snappy
(Parquet)。压缩率较 高,读写速度快。 - 避免无压缩:
始终在格式支持范围内启用压缩(如df.to_csv(compression="gzip")
)。
4. 关键注意事项
- 数据类型影响:数值类型(如
int32
vsint64
)和分类数据 (category
dtype)可进一步优化存储。 - 分块存储:对超大数据集,使用Parquet分块存储(
partition_cols
)可提升查询效率。 - 兼容性:
- Parquet:适合跨平台、长期存储。
- Feather:适合短期Python内部使用。
- Pickle:仅限Python,版本敏感,慎用。
总结
- 最优选择:Parquet +
gzip
/brotli
(需要空间极致优化)。 - 次优选择:Feather +
zstd
(需要快速读写且空间友好)。 - 避免使用:未压缩的CSV/JSON/Excel。
根据数据特征(稀疏性、列重复值)调整压缩算法,并优先选择列式存储格式以最大限度节省磁盘空间。
实际对比:pickle vs parquet
下面是一个存储了许多基因注释信息的pandas dataframe,维度为 (36875, 6)
。
我们先尝试使用pickle格式存储:
结果如下:
是否开启压缩 | 写入耗时 | 读取耗时 | 文件大小 |
---|---|---|---|
开启lzma压缩 | 2.46s | 99.8ms | 1.1MB |
不开启压缩 | 54.5ms | 28.1ms | 6.2MB |
接下来,尝试用parquet格式存储:
结果如下:
是否开启压缩 | 写入耗时 | 读取耗时 | 文件大小 |
---|---|---|---|
开启snappy压缩(默认) | 67.8ms | 41.7ms | 2.9MB |
开启brotli压缩 | 390ms | 45.7ms | 1.6MB |
开启zstd压缩 | 78.3ms | 50.9ms | 1.9MB |
如果只看压缩比率,那么pickle格式+lzma压缩率最高。
如果只看读写速度,那么pickle格式最快。
但是!
如果综合考虑压缩比率和读写速度,其实parquet格式是更好一点的 ,其对数据有一些压缩,且速度没有下降的很厉害。最重要的是parquet的兼容性是比较好的,在许多数据分析工具里面都可以用,不像pickle只能在python里面用且不同版本之间存在兼容性问题。
因此,非常推荐大家尝试一下这个格式 ~ 。(✿◡‿◡)