说明:Parquet、Feather 都是基于 Apache Arrow 的列式二进制存储格式,对比 CSV / Excel:体积更小、IO 更快、支持数据类型保留、支持分区、支持压缩;适合大数据离线分析、机器学习数据集。
两者区别简单记:
- Parquet:成熟、生态强,支持分区、嵌套结构,Hive/Spark 通用,长期归档首选;
- Feather:更轻量,设计目标是 Python/R 之间快速交换 DataFrame,读写速度略快,单表临时传递首选。
1. 环境安装
# 推荐 pyarrow 引擎(跨平台稳定)
pip install pandas pyarrow
# 备选 fastparquet(部分老集群环境用)
# pip install fastparquet
⚠️ 注意:读写 Feather 同样依赖 pyarrow。
2. 基础语法
Parquet
pd.read_parquet(
path,
engine="pyarrow", # pyarrow / fastparquet
columns=None, # 只读取指定列,减少内存
filters=None, # 行过滤(下推,不需要加载全表)
use_threads=True,
storage_options=None # s3/oss 等对象存储参数
)
df.to_parquet(
path,
engine="pyarrow",
compression="snappy", # snappy / gzip / brotli / none
partition_cols=None, # 生成分区目录
index=False # 一般不保存index,节省空间
)
Feather
pd.read_feather(
path,
columns=None,
use_threads=True,
storage_options=None
)
df.to_feather(
path,
compression="zstd", # zstd / lz4 / uncompressed
compression_level=None
)
3. 最简示例:读写单文件
import pandas as pd
# 构造测试数据
df = pd.DataFrame({
"id": [1,2,3,4,5],
"name": ["A","B","C","D","E"],
"value": [12.3, 45.6, 78.9, 11.2, 33.4],
"dt": pd.date_range("2026-01-01", periods=5)
})
# 写入 Parquet
df.to_parquet("data.parquet", engine="pyarrow", compression="snappy", index=False)
# 读取 Parquet
df_pq = pd.read_parquet("data.parquet")
print("Parquet:\n", df_pq)
# 写入 Feather
df.to_feather("data.feather", compression="zstd")
# 读取 Feather
df_ft = pd.read_feather("data.feather")
print("Feather:\n", df_ft)
4. 核心实用技巧
4.1 只读取需要的列(节省内存,高频推荐)
CSV 是全读再筛选;Parquet/Feather 可以直接只加载指定列:
# 只读取 id、name 两列
df = pd.read_parquet("data.parquet", columns=["id", "name"])
print(df)
4.2 Parquet 行过滤下推 filters(重要性能点)
不需要把整个文件读进内存再 df[df["id"]>2],交给引擎过滤:
# 语法:[(列名, 比较符, 值)]
filters = [("id", ">", 2)]
df = pd.read_parquet("data.parquet", filters=filters)
print(df)
支持多条件:
filters=[("id",">",2), ("name","in",["C","D"])]
❗ Feather 不支持 filters 行下推,这是和 Parquet 的一大差异。
4.3 分区 Parquet 读取(目录式分区)
写入生成分区:
# 按 dt 日期分区写入
df.to_parquet(
"pq_partition/",
partition_cols=["dt"],
engine="pyarrow",
index=False
)
目录结构:
pq_partition/
├── dt=2026-01-01/
│ └── ...parquet
├── dt=2026-01-02/
│ └── ...parquet
读取整个分区目录:
df = pd.read_parquet("pq_partition/")
读取分区同时过滤分区(下推,只加载对应分区):
filters = [("dt", "==", pd.to_datetime("2026-01-01"))]
df = pd.read_parquet("pq_partition/", filters=filters)
4.4 压缩选型参考
Parquet compression:
snappy:平衡速度与压缩率,日常默认首选gzip:压缩率更高,读写慢一点,归档用none:不压缩,最快,占用空间大
Feather compression:
zstd:默认推荐,压缩率好,速度优秀lz4:极致读写速度,压缩弱一点
5. 读取远程对象存储(S3 / OSS)
# S3 示例,依赖 s3fs
# pip install s3fs
df = pd.read_parquet(
"s3://bucket/path/data.parquet",
storage_options={
"key": "AK",
"secret": "SK",
"endpoint_url": "[https://xxx.oss-cn-hangzhou.aliyuncs.com](https://xxx.oss-cn-hangzhou.aliyuncs.com)"
}
)
Feather 写法一致,同样支持 storage_options。
6. 类型保留特性演示
CSV 会丢失日期、整数类型,读出来经常变成 object;Parquet / Feather 原生保留 dtype:
print(df_pq.dtypes)
'''
id int64
name object
value float64
dt datetime64[ns]
dtype: object
'''
7. 对比表
| 特性 | Parquet | Feather | CSV |
|---|---|---|---|
| 文件大小 | 很小 | 小 | 大 |
| 列裁剪 | ✅ | ✅ | ❌ |
| 行过滤下推 | ✅ | ❌ | ❌ |
| 分区支持 | ✅ | ❌ | ❌ |
| 嵌套结构 | ✅ | ❌ | ❌ |
| 跨语言生态 | Spark/Hive/Python/R | Python/R | 全语言 |
| 读写速度 | 快 | 更快 | 慢 |
| 适合场景 | 大数据、数仓、归档 | 本地快速交换DF | 简单导出、给人看 |
8. 常见坑 & 报错
- ArrowInvalid / 引擎不存在
忘记装 pyarrow;或者环境同时装 pyarrow / fastparquet,版本冲突。优先固定engine="pyarrow"。 - 分区字段读取变成字符串
pyarrow 老版本分区时间类型识别异常,升级 pyarrow。 - Feather 不适合长期归档
Feather 格式规范迭代更快,跨大版本兼容性不如 Parquet;长期存储优先 Parquet。 - 索引保存问题
to_parquet(index=True)会把索引单独存一列;绝大多数业务不需要,统一index=False。 - 超大单 parquet 文件
单文件不要几百GB,建议拆分成多个文件(按日期/ID分区)。 - windows长路径:pyarrow 偶尔路径报错,路径尽量简短。
9. 清洗导出完整示例
import pandas as pd
# 读取分区parquet,过滤+选列
df = pd.read_parquet(
"pq_partition/",
columns=["id", "name", "value"],
filters=[("id", ">", 1)]
)
# 简单清洗
df = df.dropna()
df = df[df["value"] > 10]
# 导出
df.to_excel("pq_result.xlsx", index=False)
df.to_feather("clean_result.feather")
print("清洗完成,行数:", len(df))
10. 什么时候选哪个?
- 离线报表、大数据、和 Spark 互通、按分区筛选数据 → Parquet + snappy
- 本地脚本之间传递 DataFrame、机器学习数据集临时缓存、追求最快读写 → Feather + zstd
- 需要发给业务人员打开查看 → CSV / Excel
0 条笔记