自学教程 学编程从这里开始

Pandas 读取 Parquet / Feather 文件

说明: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. 对比表

特性ParquetFeatherCSV
文件大小很小小大
列裁剪✅✅❌
行过滤下推✅❌❌
分区支持✅❌❌
嵌套结构✅❌❌
跨语言生态Spark/Hive/Python/RPython/R全语言
读写速度快更快慢
适合场景大数据、数仓、归档本地快速交换DF简单导出、给人看

8. 常见坑 & 报错

  1. ArrowInvalid / 引擎不存在

    忘记装 pyarrow;或者环境同时装 pyarrow / fastparquet,版本冲突。优先固定 engine="pyarrow"。
  2. 分区字段读取变成字符串

    pyarrow 老版本分区时间类型识别异常,升级 pyarrow。
  3. Feather 不适合长期归档

    Feather 格式规范迭代更快,跨大版本兼容性不如 Parquet;长期存储优先 Parquet。
  4. 索引保存问题

    to_parquet(index=True) 会把索引单独存一列;绝大多数业务不需要,统一 index=False。
  5. 超大单 parquet 文件

    单文件不要几百GB,建议拆分成多个文件(按日期/ID分区)。
  6. 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 条笔记