You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars DataFrame内存占用远超预估,是否解读有误?

Polars DataFrame内存占用与estimated_size()差异的原因分析及解决方案

核心原因拆解

  • estimated_size()的局限性:该方法仅统计DataFrame列数据的原始字节大小,不包含Polars内部的元数据、内存对齐开销、空值标记、类型管理结构等额外存储,也未计算Python解释器对对象的内存占用。
  • Parquet加载的内存膨胀点:
    • 字符串类型:Parquet中是压缩存储,加载到内存后会还原为UTF-8原始字节,加上Polars维护的长度数组等管理结构,额外占用内存。
    • 数值类型:Parquet可能用压缩编码存储小位宽数值,加载后会转为Polars默认的64位整数/浮点数,内存占用直接翻倍甚至更多。
  • 系统内存统计的偏差:Docker的内存统计包含进程整个地址空间(如共享库、缓存页),并非DataFrame独占内存,不能直接作为精准参考。

验证与优化步骤

  1. 用memory_usage()精准统计:
    直接获取DataFrame自身的内存占用,替代系统级监控:
    import polars as pl
    df = pl.read_parquet("your_file.parquet")
    # 查看每列内存占用
    print(df.memory_usage())
    # 查看总内存占用
    print(df.memory_usage().sum())
    
    这个结果包含Polars内部存储开销,比estimated_size()更贴近实际。
  2. 优化数据类型:
    • 先查看列类型:print(df.schema),将宽类型转为窄类型,比如Int64转Int32/Int16,Float64转Float32,直接降低内存占用。
    • 字符串列若存在大量重复值,转为Categorical类型:df = df.with_columns(pl.col("str_col").cast(pl.Categorical)),重复值越多,内存节省越明显。
  3. 分批处理大数据:
    处理数百万条记录时,采用流式分批加载,避免一次性加载全量数据:
    # 按批次读取并处理
    for batch in pl.scan_parquet("large_file.parquet").streaming().batches(batch_size=100_000):
        process_batch(batch)
    
    流式处理仅将当前批次加载到内存,内存占用可控。

总结

estimated_size()只是粗略参考值,实际内存占用包含Polars内部存储开销和数据类型转换后的额外占用。通过memory_usage()精准统计,配合类型优化、分批加载,完全可以将内存控制在合理范围,支撑数十万到数百万条记录的处理。

内容的提问来源于stack exchange,提问作者AvitanD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:20:05