马儿慢些走

人生惶惶,悲喜一场。

Polars 高效合并与压缩保存 `.jsonl.gz` 的实战方案(Gemini)

[!NOTE]
2026年2月6日,本文为个人和 AI 大模型 Gemini 的对话再由 Gemini 进行总结生成,仅供参考。

技术笔记:Polars 高效合并与压缩保存 .jsonl.gz 的实战方案

在处理大规模 DataFrame(如 13 万行以上的文本与元数据)时,如何高效合并数据并以压缩格式持久化是数据工程中的常见挑战。本笔记总结了从 Polars 数据合并到解决 jsonl.gz 压缩性能瓶颈的完整演进过程。


1. 核心场景描述

  • 任务:将 df_subject 中的学科标签(final_subjects)和概率映射(final_result_map)合并到 df_text 主表中。
  • 字段特性:包含长文本(text)、列表(list[str])和结构化字符串(JSON)。
  • 导出要求:保存为行分隔的 JSON 格式(JSONL)并进行 Gzip 压缩。

2. 数据合并(Join)的最佳实践

Polars 的 join 操作基于 Rust 编写,性能远超 Pandas。

import polars as pl

# 推荐写法:先 select 目标列,避免产生重名列后缀(如 _right)
df_merged = df_text.join(
    df_subject.select(["id", "final_subjects", "final_result_map"]),
    on="id",
    how="left"
)
  • 注意:在合并大规模散乱数据后,建议执行 df_merged.rechunk()。它能重新分配内存使数据连续,提升后续序列化(写入)的速度。

3. 痛点:Polars write_ndjson 的局限性

在尝试直接压缩保存时,会遇到以下问题:

  1. 参数缺失:Polars 的 write_ndjson() 函数不像 write_csv() 那样原生支持 compression="gzip" 参数。直接传入该参数会触发 TypeError
  2. 标准库性能低下:使用 Python 内置的 gzip 模块(如 gzip.open)配合 Polars 写入,虽然能解决压缩问题,但由于 gzip 模块是单线程运行且通过 Python I/O 中转,数据处理速度极慢。
  3. 压缩等级陷阱:内置 gzip 默认 compresslevel=9,这会导致 CPU 消耗极高而写入速度断崖式下跌。

4. 高性能解决方案:isal 库的应用

为了突破 Python 标准库的性能瓶颈,推荐使用 Intel Storage Acceleration Library (ISA-L) 的 Python 封装库 isal

方案实现:
  1. 安装pip install isal
  2. 代码实现
from isal import igzip

def fast_save_jsonl_gz(df: pl.DataFrame, output_path: str):
    # 使用 igzip 提供高性能压缩
    # compresslevel=1 或 2 即可在极速下获得很高的压缩比
    with igzip.open(output_path, "wb", compresslevel=2) as f:
        df.write_ndjson(f)
为什么 isal.igzip 更快?
  • 算法优化isal 利用了现代 CPU 的汇编优化(如多级流水线指令),在相同压缩比下,速度可达标准 gzip 模块的 5-10 倍
  • 流式写入:Polars 的 write_ndjson 接受任何具有 .write() 方法的文件对象。通过将 igzip 对象传给 Polars,数据可以直接从内存流向压缩引擎,无需生成巨大的临时中间文件。

5. 进阶性能调优建议

  • 调整压缩级别:对于 jsonl.gz,通常 compresslevel=13 之间性价比最高。级别越高,CPU 消耗呈指数增长,但文件体积缩减幅度递减。
  • 读取自动化:Polars 的 read_ndjson() 具有智能头信息识别功能。即使是 isal 压缩的文件,只要后缀是 .gz,直接使用 pl.read_ndjson("file.jsonl.gz") 即可自动解压读取,无需手动干预。
  • 备选格式:如果下游环境允许,Parquetdf.write_parquet(..., compression="zstd"))是 Polars 的原生“本命”格式,其压缩率和读写性能均优于 JSONL。

总结

在 Polars 中处理 .jsonl.gz 时, “Polars 负责序列化 + isal 负责高性能压缩” 是目前兼顾通用性与极致速度的最佳组合方案。

posted on 2026-02-06 10:32  马儿慢些走  阅读(0)  评论(0)    收藏  举报

导航