Pandas入门教程(十三):Parquet 与 Feather——高性能列式存储格式实战

一、为什么使用 Parquet 和 Feather?

Parquet 和 Feather 是两种高效的列式数据存储格式,专为大数据分析和快速读写场景设计。相比 CSV,它们具有更好的压缩比和查询性能。

列式存储格式的主要优势:

特性 CSV Parquet Feather
存储格式 行式 列式 列式
读取速度 慢 很快 极快
写入速度 中 快 极快
压缩率 低 高 中
跨语言支持 通用 Java/Python/R Python/R

定位说明:

  • Parquet 是 Apache 基金会的项目,被广泛用于大数据生态(Hadoop、Spark、DuckDB 等)。

  • Feather 是 Arrow 项目的原生实现,专注于极致的读写速度。

一句话选择: 长期存储、跨生态协作用 Parquet;临时缓存、进程间传递用 Feather。

二、Parquet 文件操作
1. 安装依赖

bash

复制代码
pip install pyarrow fastparquet

PyArrow 和 FastParquet 都是 Parquet 的 Python 实现,PyArrow 是默认选项,FastParquet 在某些场景下更快。

两种引擎对比:

引擎 特点 推荐场景
pyarrow 默认,生态完善 通用首选
fastparquet 某些场景更快 性能敏感场景
2. 读取 Parquet 文件

python

复制代码
import pandas as pd

# 读取 Parquet 文件(默认使用 pyarrow)
df = pd.read_parquet("data.parquet")

# 指定使用特定的引擎
df = pd.read_parquet("data.parquet", engine="pyarrow")
df = pd.read_parquet("data.parquet", engine="fastparquet")

# 读取远程 Parquet 文件
df = pd.read_parquet("s3://bucket/data.parquet")

# 读取文件的某些列(列裁剪,提升性能)
df = pd.read_parquet("data.parquet", columns=["name", "age", "city"])
print(df.head())

列裁剪的优势: 列式存储的核心优势------只读取需要的列,不加载无关数据,大幅提升查询性能。

3. 写入 Parquet 文件

python

复制代码
import pandas as pd

# 准备测试数据
df = pd.DataFrame({
    "id": range(1, 10001),
    "name": ["用户" + str(i) for i in range(1, 10001)],
    "age": [20, 25, 30, 35] * 2500,
    "city": ["北京", "上海", "广州", "深圳"] * 2500,
    "score": [round(i * 0.1, 2) for i in range(1, 10001)]
})

# 写入 Parquet 文件(默认使用 pyarrow 引擎)
df.to_parquet("data.parquet", index=False)

# 指定压缩方式(snappy 速度快,gzip 压缩率高)
df.to_parquet("data_snappy.parquet", compression="snappy", index=False)
df.to_parquet("data_gzip.parquet", compression="gzip", index=False)
df.to_parquet("data_none.parquet", compression=None, index=False)   # 不压缩

# 查看文件大小
import os
print("文件大小对比:")
print(f"原始 CSV 预估: {len(df) * 50 / 1024 / 1024:.2f} MB")
print(f"snappy 压缩: {os.path.getsize('data_snappy.parquet') / 1024 / 1024:.2f} MB")
print(f"gzip 压缩: {os.path.getsize('data_gzip.parquet') / 1024 / 1024:.2f} MB")
print(f"无压缩: {os.path.getsize('data_none.parquet') / 1024 / 1024:.2f} MB")

Parquet 压缩方式对比:

压缩方式 速度 压缩率 适用场景
snappy(默认) 快 中 通用首选
gzip 慢 高 存储优先
zstd 中 高 平衡之选
None 最快 无 临时文件
4. 测试不同引擎的写入性能

python

复制代码
import pandas as pd
import time

# 测试不同引擎的写入性能
df = pd.DataFrame({
    "id": range(1, 100001),
    "value": range(1, 100001)
})

# pyarrow 引擎写入
start = time.time()
df.to_parquet("test_pyarrow.parquet", engine="pyarrow", compression="snappy")
print(f"pyarrow 写入时间: {time.time() - start:.3f}s")

# fastparquet 引擎写入
start = time.time()
df.to_parquet("test_fastparquet.parquet", engine="fastparquet", compression="snappy")
print(f"fastparquet 写入时间: {time.time() - start:.3f}s")

建议: 先跑一遍测试,根据实际数据特征选择更快的引擎。

三、Feather 文件操作

Feather 是 Arrow 项目的 Python 实现,专注于极致的内存读写速度。

1. 安装依赖

bash

复制代码
pip install pyarrow
2. 读取 Feather 文件

python

复制代码
import pandas as pd

# 读取 Feather 文件
df = pd.read_feather("data.feather")

# 读取 v2 版本的 Feather 文件(更通用)
df = pd.read_feather("data.feather", version="2.0")

# 读取某些列
df = pd.read_feather("data.feather", columns=["name", "age"])
print(df.head())

Feather 版本说明:

版本 特点
v1 早期版本,兼容性有限
v2(推荐) 基于 Arrow IPC 格式,更通用
3. 写入 Feather 文件

python

复制代码
import pandas as pd

# 准备测试数据
df = pd.DataFrame({
    "id": range(1, 10001),
    "name": ["用户" + str(i) for i in range(1, 10001)],
    "value": [round(i * 0.1, 2) for i in range(1, 10001)]
})

# 写入 Feather 文件
df.to_feather("data.feather")

# LZ4 压缩(更快)
df.to_feather("data_lz4.feather", compression="lz4")

# ZSTD 压缩(压缩率更高)
df.to_feather("data_zstd.feather", compression="zstd")

# 查看文件大小
import os
print(f"无压缩: {os.path.getsize('data.feather') / 1024:.2f} KB")
print(f"LZ4: {os.path.getsize('data_lz4.feather') / 1024:.2f} KB")
print(f"ZSTD: {os.path.getsize('data_zstd.feather') / 1024:.2f} KB")

Feather 压缩方式对比:

压缩方式 速度 压缩率 适用场景
无压缩(默认) 最快 无 内存传递
lz4 快 中 平衡速度与体积
zstd 中 高 存储优先
四、性能对比测试

下面用 100 万行数据对比 CSV、Parquet、Feather 三种格式的读写性能:

python

复制代码
import pandas as pd
import numpy as np
import time
import os
import tempfile

# 创建测试数据
np.random.seed(42)
n_rows = 1000000
df = pd.DataFrame({
    "id": range(n_rows),
    "category": np.random.choice(["A", "B", "C", "D"], n_rows),
    "value": np.random.randn(n_rows),
    "flag": np.random.choice([True, False], n_rows),
    "date": pd.date_range("2020-01-01", periods=n_rows, freq="1min")
})

# 创建临时目录
with tempfile.TemporaryDirectory() as tmpdir:
    # CSV 写入
    start = time.time()
    df.to_csv(f"{tmpdir}/data.csv", index=False)
    csv_write = time.time() - start

    start = time.time()
    df_csv = pd.read_csv(f"{tmpdir}/data.csv")
    csv_read = time.time() - start

    # Parquet 写入
    start = time.time()
    df.to_parquet(f"{tmpdir}/data.parquet", index=False)
    pq_write = time.time() - start

    start = time.time()
    df_pq = pd.read_parquet(f"{tmpdir}/data.parquet")
    pq_read = time.time() - start

    # Feather 写入
    start = time.time()
    df.to_feather(f"{tmpdir}/data.feather")
    feather_write = time.time() - start

    start = time.time()
    df_feather = pd.read_feather(f"{tmpdir}/data.feather")
    feather_read = time.time() - start

    # 输出结果
    print(f"{'格式':<10} {'写入时间':<12} {'读取时间':<12} {'文件大小':<12}")
    print("-" * 50)
    print(f"{'CSV':<10} {csv_write:.3f}s{'':<5} {csv_read:.3f}s{'':<5} {os.path.getsize(f'{tmpdir}/data.csv')/1024/1024:.2f}MB")
    print(f"{'Parquet':<10} {pq_write:.3f}s{'':<5} {pq_read:.3f}s{'':<5} {os.path.getsize(f'{tmpdir}/data.parquet')/1024/1024:.2f}MB")
    print(f"{'Feather':<10} {feather_write:.3f}s{'':<5} {feather_read:.3f}s{'':<5} {os.path.getsize(f'{tmpdir}/data.feather')/1024/1024:.2f}MB")

典型测试结果(100 万行 × 5 列):

格式 写入时间 读取时间 文件大小
CSV 约 3-5s 约 1-2s 约 50-60 MB
Parquet 约 0.3-0.5s 约 0.1-0.2s 约 10-15 MB
Feather 约 0.1-0.2s 约 0.05-0.1s 约 20-25 MB

测试说明: 具体数值因硬件和数据特征而异,但量级关系基本一致------Parquet 和 Feather 比 CSV 快一个数量级,文件体积小数倍。

性能差异原因:

原因 说明
列式存储 只读需要的列,减少 IO
二进制格式 无需文本解析,直接映射内存
高效压缩 同列数据相似度高,压缩率高
类型信息 保留 dtype,无需推断
五、使用场景与选择建议
场景 推荐格式 原因
大数据分析 Parquet 高压缩比,列式查询快,生态广泛
Python/R 数据传递 Feather 极快读写,Arrow 原生支持
Spark/Hadoop 集成 Parquet 大数据生态标准格式
数据备份/归档 Parquet 压缩率高,支持 schema 演进
临时数据缓存 Feather 读写最快
与 Excel 用户交换 CSV 通用可读

选择决策流程:

六、格式对比速查表
对比项 CSV Parquet Feather
存储格式 行式文本 列式二进制 列式二进制
读取速度 慢 很快 极快
写入速度 中 快 极快
压缩率 低 高 中
文件大小 大 很小 中
跨语言 通用 Java/Python/R Python/R
人工可读 ✅ ❌ ❌
列裁剪 ❌ ✅ ✅
依赖库 内置 pyarrow pyarrow
推荐场景 交换 存储分析 临时缓存
七、读写流程图
八、常用参数速查
需求 Parquet Feather
基础读取 pd.read_parquet("f.parquet") pd.read_feather("f.feather")
指定引擎 engine="pyarrow" ---
读取部分列 columns=["a","b"] columns=["a","b"]
基础写入 df.to_parquet("f.parquet") df.to_feather("f.feather")
不写索引 index=False 默认不写索引
高压缩 compression="gzip" compression="zstd"
快压缩 compression="snappy" compression="lz4"
不压缩 compression=None 默认无压缩
读取远程 s3://bucket/f.parquet ---
九、常见问题与注意事项

1. 读取 Parquet 报错

确保安装了 pyarrow 或 fastparquet:

bash

复制代码
pip install pyarrow

2. 文件损坏

写入时确保数据完整写入磁盘,建议写入后验证文件可读性:

python

复制代码
df.to_parquet("data.parquet", index=False)
# 写入后验证
df_check = pd.read_parquet("data.parquet")
assert len(df_check) == len(df), "数据行数不一致"

3. 版本兼容

不同版本的 Parquet 可能存在兼容性问题,建议在项目中使用固定版本。

4. Feather 版本选择

python

复制代码
# 写入 v2 版本(推荐,更通用)
df.to_feather("data.feather")

# 读取时指定版本
df = pd.read_feather("data.feather", version="2.0")
十、常见问题排查
问题现象 可能原因 解决方案
ImportError: pyarrow 未安装引擎 pip install pyarrow
ArrowInvalid 文件格式损坏 重新写入,检查磁盘
读取列名报错 columns 拼写错误 检查列名是否存在于文件
文件比 CSV 还大 未启用压缩 设置 compression="snappy"
写入速度慢 压缩率过高 改用 snappy 或 lz4
S3 读取失败 未配置凭证 配置 AWS 凭证或改用本地
数据类型丢失 版本不兼容 固定 pyarrow 版本
十一、小结

本篇你掌握了 Parquet 与 Feather 两种高性能列式存储格式:

  • 格式定位:Parquet 适合大数据生态与长期存储,Feather 适合极致速度与临时缓存。

  • Parquet 读写 :read_parquet / to_parquet,支持 pyarrow 与 fastparquet 引擎。

  • Feather 读写 :read_feather / to_feather,推荐 v2 版本。

  • 压缩方式 :Parquet 用 snappy、gzip、zstd;Feather 用 lz4、zstd。

  • 列裁剪 :columns 参数只读取需要的列,提升性能。

  • 性能对比:百万行数据下,Parquet 和 Feather 比 CSV 快一个数量级,文件小数倍。

  • 选型建议:大数据分析用 Parquet,数据传递用 Feather,人工交换用 CSV。

数据量增长后,选择合适的存储格式能显著提升效率。下一篇我们将学习 Pandas 数据清洗,掌握缺失值、重复值、异常值的系统处理方法。

相关推荐
gCode Teacher 格码致知4 小时前
Pandas教学-21:subplots的使用
python·pandas·1024程序员节
benchmark_cc4 小时前
量化开发中,什么时候应该停止手动下载股票数据?
python·数据分析·pandas·量化交易·1024程序员节·股票数据·quantdash
quantdash_cc10 小时前
如何利用标的信息为研究股票池补充名称和交易所信息?
开发语言·python·pandas·量化交易·1024程序员节·股票数据·quantdash
benchmark_cc1 天前
QuantDash 安装成功后,如何验证 Python 环境可以正常导入 SDK?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
benchmark_cc1 天前
个人量化系统搭建:如何利用 QuantDash 实现 A 股日 K 线前复权数据的高效获取与质量校验?
python·数据分析·pandas·量化交易·股票数据·quantdash
烂蜻蜓2 天前
Pandas入门教程(十二):读取 HTML 表格——read_html 参数详解与网页数据清洗
python·html·pandas
quantdash_cc2 天前
如何从多只股票的历史行情构建收益率矩阵?Python 与 QuantDash 实战教程
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
gCode Teacher 格码致知2 天前
Pandas教学-18:number与numeric的区别
python·pandas
量化炼金 (CodeAlchemy)3 天前
【Python】pandas vs polars 简单性能对比测试
开发语言·python·pandas