Polars与Pandas读取超宽数据集的性能差异及调试方法
超宽数据集读写性能差异问题
我有一个包含约50万列的超宽数据集,同时存储为Parquet和CSV格式。测试发现以下性能差异:
- Polars读取CSV速度极快,但Pandas读取CSV耗时超30分钟后崩溃;
- Pandas读取Parquet仅需约30秒,但Polars读取Parquet耗时长达30分钟。
测试代码如下:
# 文件路径,两个文件存储相同数据,包含10万列 parquet_path = '.....' csv_path = '.....' import polars as pl import pandas as pd data_pl_parquet = pl.read_parquet(parquet_path) # 耗时极久,约30分钟 data_pl_csv = pl.read_csv(csv_path) # 速度极快,仅需30秒 data_pd_parquet = pd.read_parquet(parquet_path) # 速度极快,仅需30秒 data_pd_csv = pd.read_csv(csv_path) # 耗时超30分钟后崩溃 # 那先用Pandas读取Parquet再转成Polars呢? pl.from_pandas(data_pd_parquet) # 仅需30秒
请问这是什么原因导致两者表现差异巨大?该如何进一步调试排查?
核心原因分析
1. CSV读写差异根源
- Pandas的CSV读取采用逐行解析+全局类型推断逻辑,面对50万级超宽列时,每一行都要匹配上万列的类型,内存开销和计算量呈指数级增长,最终因内存不足崩溃。
- Polars是列式解析,读取CSV时先批量扫描列类型,再整列读取数据,加上Rust底层的高效内存管理,超宽场景下的性能优势被放大,因此速度极快。
2. Parquet读写差异根源
- Pandas依赖
pyarrow或fastparquet作为Parquet引擎,这两个库对超宽列Parquet做了针对性优化:批量加载列元数据、直接利用Arrow列式存储特性映射到Pandas结构,所以读取速度快。 - Polars自带的Parquet读取逻辑在超宽列场景下存在元数据解析瓶颈:对每一列的类型、编码等信息逐个处理,50万列的量级会让元数据解析消耗大量时间;且其默认引擎的超宽场景优化不如pyarrow成熟,导致整体读取缓慢。
pl.from_pandas直接复用Pandas已加载的内存数据,跳过了Parquet解析流程,因此速度和Pandas读取Parquet相当。
调试排查步骤
1. 定位Polars读取Parquet的瓶颈
- 开启日志调试,查看是元数据解析还是数据加载阶段耗时:
import logging logging.basicConfig(level=logging.DEBUG) data_pl_parquet = pl.read_parquet(parquet_path) - 拆分流程对比元数据读取耗时:用pyarrow单独读取元数据,再和Polars的耗时对比:
import pyarrow.parquet as pq import time start = time.time() parquet_file = pq.ParquetFile(parquet_path) schema = parquet_file.schema print(f"pyarrow读取元数据耗时:{time.time()-start}秒")
2. 验证Polars的Parquet引擎选项
- 指定Polars使用
pyarrow作为Parquet引擎,测试是否提升速度:
如果速度明显提升,说明Polars自带引擎在超宽场景下优化不足。data_pl_parquet = pl.read_parquet(parquet_path, use_pyarrow=True)
3. 检查Parquet文件存储格式
- 用
pq.ParquetFile(parquet_path).metadata查看文件分块信息,判断是否存在分块过多、列存储布局不合理的情况——这类问题会导致Polars频繁IO,拖慢读取速度。
4. 监控内存与CPU状态
- 用
top或htop实时监控读取过程:- 若CPU占用低,可能是IO等待或元数据解析阻塞;
- 若内存占用异常高,可能是Polars的数据加载内存分配策略存在问题。
内容的提问来源于stack exchange,提问作者dalloliogm
相关产品推荐
相关产品推荐

