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

Pandas多分组内存占用优化求助:1400万行DataFrame内存过高

优化大DataFrame分组操作的内存占用方案

一、直接优化分组计算逻辑

  • 提前筛选必要列:你当前的代码先全量分组再取目标列,完全可以先只保留分组键(ds, item, location)和regressor列再执行分组,大幅减少内存负载:
    # 仅保留参与计算的必要列
    reduced_df = regressor_df[['ds', 'item', 'location', regressor]]
    regressor_prediction = reduced_df.groupby(['ds', 'item', 'location']).mean().reset_index().fillna(0.)
    # 手动释放临时DataFrame内存
    del reduced_df
    import gc
    gc.collect()
    
  • 拆分链式操作,清理中间对象:原链式调用会产生多个未被引用的中间DataFrame,拆分步骤后显式删除中间变量并触发垃圾回收:
    grouped = regressor_df.groupby(['ds', 'item', 'location'])[regressor].mean()
    regressor_prediction = grouped.reset_index().fillna(0.)
    # 删除分组对象,释放占用的内存
    del grouped
    gc.collect()
    

二、分块处理的正确姿势(解决你之前分块无效的问题)

之前分块没用大概率是因为没及时释放每块的内存,或是分块维度不对。试试按location字段分块(这个字段是内存差异的核心):

regressor_prediction = []
# 按location唯一值遍历,每次仅处理单个location的数据
for loc in regressor_df['location'].unique():
    chunk = regressor_df[regressor_df['location'] == loc][['ds', 'item', regressor]]
    chunk_grouped = chunk.groupby(['ds', 'item']).mean().reset_index()
    chunk_grouped['location'] = loc
    regressor_prediction.append(chunk_grouped)
    # 每处理完一块就清理内存
    del chunk, chunk_grouped
    gc.collect()
# 合并所有分块结果
regressor_prediction = pd.concat(regressor_prediction, ignore_index=True).fillna(0.)

这种方式每次仅加载单个location的子集,不会让全量数据驻留内存,内存占用会显著降低。

三、内存优化前置操作

  • 压缩数据类型:检查regressor_df各列的类型,把item和location转成category类型,日期字符串ds转成datetime64,能大幅减少内存占用:
    regressor_df['item'] = regressor_df['item'].astype('category')
    regressor_df['location'] = regressor_df['location'].astype('category')
    # 若ds是字符串格式的日期,按实际格式转换
    regressor_df['ds'] = pd.to_datetime(regressor_df['ds'], format='%Y-%m-%d')
    
  • 及时释放原始数据内存:如果分组完成后regressor_df不再需要,立刻删除并回收内存:
    del regressor_df
    gc.collect()
    

四、备选:用Dask实现自动分块处理

如果以上方法仍无法满足需求,改用Dask DataFrame替代Pandas,它天生支持分块计算,无需手动管理内存:

import dask.dataframe as dd

# 按CPU核心数设置分区数
dask_df = dd.from_pandas(regressor_df, npartitions=8)
result = dask_df.groupby(['ds', 'item', 'location'])[regressor].mean().reset_index().fillna(0.)
regressor_prediction = result.compute()

Dask会自动将数据拆分后并行处理,不会一次性加载全量数据到内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:12:14