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

在Jupyter Notebook中使用Matplotlib批量绘图为何会耗尽RAM?

解决Matplotlib循环生成图片内存耗尽问题

针对你循环生成40000张图片时的内存耗尽问题——即便调用了plt.clf()和plt.close()仍未解决,核心原因是全局绘图状态的资源未彻底释放以及Pandas拼接操作的内存累积,可通过以下方法优化:

1. 显式管理Figure和Axes对象

别依赖Matplotlib的全局绘图接口(比如plt.matshow),显式创建Figure和Axes对象,确保每次循环都能彻底销毁资源:

  • 用plt.subplots()生成明确的图和轴对象
  • 绘图完成后直接关闭对应的Figure,而非依赖全局的plt.close()

2. 优化Pandas数据拼接逻辑

原代码每次循环都用pd.concat拼接小DataFrame,会产生大量临时对象,导致内存碎片和占用飙升。改为先把需要拼接的DataFrame收集到列表,最后一次性拼接,大幅减少内存开销。

3. 减少不必要的数据副本

避免创建冗余的DataFrame副本,比如直接在索引时获取所需数据,降低内存占用。

修改后的代码

import matplotlib.pyplot as plt
import pandas as pd

# 预提取AA中"One Letter"的映射,避免每次循环重复查询(可选但能显著提速)
aa_mapping = {letter: df.iloc[:,1:] for letter, df in AA.groupby("One Letter")}

for i in range(len(X_train)):
    tmp = X_train.iloc[i]  # 用iloc更高效,避免loc的标签查询开销
    # 收集需要拼接的数据块
    df_list = []
    for letter in range(1,5):
        target_letter = tmp[letter]
        # 直接从预映射中取数据,避免重复查询AA
        df_slice = aa_mapping[target_letter]
        df_list.append(df_slice)
    
    to_save = pd.concat(df_list, axis=0)
    
    # 显式创建Figure和Axes
    fig, ax = plt.subplots()
    ax.matshow(to_save, interpolation='none', vmin=0, vmax=1)
    ax.axis("off")  # 关闭当前轴,而非全局plt.axis
    fig.savefig(f'D:/CNN/train/df_plot{i}.png', bbox_inches="tight")
    # 彻底销毁当前图对象
    plt.close(fig)

额外优化建议

  • 如果内存仍然紧张,可在每次循环末尾手动触发Python垃圾回收:
    import gc
    gc.collect()
    
  • 检查AA数据的类型,尽量用更节省内存的dtype(比如把字符串列转为category类型),减少每次查询和拼接的内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:40:19