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

如何低内存占用将大型Polars DataFrame转换为字典?

问题解决思路与优化方案

先解决「迭代期间字典大小已更改」错误

你遇到的错误本质是在迭代字典对象的同时修改了它的结构。内层用partition_by(..., as_dict=True)生成的字典,在推导式迭代过程中可能因隐式操作触发结构变化,换用直接提取键值对的方式就能避免。

核心内存优化方案:流式分块处理(无需加载全量数据)

不要先把整个5.5GB Parquet加载到内存,用Polars的流式读取能力边读边处理,从根源减少内存占用:

import polars as pl
import gc

# 替换为你的唯一列名称
unique_col = "unique_col"
my_dict = {}

# 流式读取Parquet,按100万行分块处理
for chunk in pl.scan_parquet("你的文件路径.parquet").streaming().iter_batches(batch_size=1_000_000):
    # 对当前chunk按唯一列去重,保留最后一条记录
    chunk_unique = chunk.unique(subset=[unique_col], keep="last")
    # 将其他列打包为struct,直接生成键值对字典
    chunk_data = chunk_unique.select(
        unique_col,
        pl.struct(pl.exclude(unique_col)).alias("row_data")
    ).to_dict(as_series=False)
    # 合并到最终字典(后续chunk的重复值会覆盖前面的,符合keep='last'逻辑)
    my_dict.update(dict(zip(chunk_data[unique_col], chunk_data["row_data"])))
    # 手动释放当前chunk的内存
    del chunk, chunk_unique, chunk_data
    gc.collect()

方案优势:

  • 无需加载全量数据到内存,每个chunk仅占用单批次数据的内存,远低于5.5GB
  • 避免了多层partition_by生成中间字典的内存开销
  • 彻底规避字典迭代时的修改错误

备选优化:利用排序列加速查找(无需构建字典)

如果你的唯一列是已排序的,可以不用构建字典,直接利用Polars的排序索引做快速查找,进一步节省内存:

# 加载数据并标记唯一列为排序状态
df = pl.read_parquet("你的文件路径.parquet").set_sorted(unique_col)

# 基于排序索引的快速查找
def get_row(unique_val):
    return df.filter(pl.col(unique_col) == unique_val).select(pl.exclude(unique_col)).to_dicts()[0]

Polars会对排序后的列自动启用二分查找,比普通过滤快一个数量级,且无需额外占用字典的内存。

对你原有代码的问题分析

  1. 先加载全量DataFrame到内存,再分块处理,本质还是占用了5.5GB内存,内存优化效果有限
  2. 多层partition_by生成的中间字典(m和内层的分区字典)会额外占用大量内存
  3. 内层字典推导式可能因隐式操作触发字典结构修改,导致迭代错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:55:25