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

Jupyter Notebook多进程保存Matplotlib图时外部DataFrame调用报错解决

解决多进程中访问外部DataFrame的问题

为什么会报错?

多进程的每个子进程都有独立的内存空间,主进程中定义的全局变量df不会自动被子进程识别,因此会抛出NameError。


解决方案1:将DataFrame作为参数传递

pool.map默认只能给函数传单个参数,我们可以用pool.starmap传递多参数,或者把参数打包成元组:

import pandas as pd 
from multiprocess import Pool

df = pd.DataFrame({'A':[1,2,3],'B':[1,2,3]})

def do_plot(number, df):
    import matplotlib.pyplot as plt
    
    fig = plt.figure(number)
    a = df['A']
    b = df['B']
    plt.scatter(a, b)

    plt.savefig("%03d.jpg" % (number,))
    plt.close()
    print("Done ", number)

if __name__ == '__main__':  # 必须添加,避免多进程启动时重复执行代码
    pool = Pool(4)
    # 打包每个任务的参数
    tasks = [(num, df) for num in range(4)]
    pool.starmap(do_plot, tasks)

⚠️ 注意:如果DataFrame体积很大,这种方法会把df复制到每个子进程,占用较多内存。


解决方案2:子进程内部加载DataFrame

如果你的DataFrame是从文件(CSV/Excel等)读取的,可以让每个子进程自行加载,避免主进程复制大对象:

import pandas as pd 
from multiprocess import Pool

def do_plot(number):
    import matplotlib.pyplot as plt
    # 子进程内部读取文件生成DataFrame
    df = pd.read_csv('your_data.csv')  # 替换为你的文件路径
    
    fig = plt.figure(number)
    a = df['A']
    b = df['B']
    plt.scatter(a, b)

    plt.savefig("%03d.jpg" % (number,))
    plt.close()
    print("Done ", number)

if __name__ == '__main__':
    pool = Pool(4)
    pool.map(do_plot, range(4))

这种方法节省内存,但要注意文件读取的IO开销,适合大型数据集场景。


解决方案3:使用共享内存(超大型DataFrame专用)

如果DataFrame极大,不想多次复制,可以通过共享内存传递数据,需先将DataFrame转为可共享的结构,再在子进程中重建:

import pandas as pd 
import numpy as np
from multiprocess import Pool, Manager

def init_worker(shared_array, columns):
    # 在子进程中初始化全局共享DataFrame
    global df_shared
    df_shared = pd.DataFrame(shared_array, columns=columns)

def do_plot(number):
    import matplotlib.pyplot as plt
    
    fig = plt.figure(number)
    a = df_shared['A']
    b = df_shared['B']
    plt.scatter(a, b)

    plt.savefig("%03d.jpg" % (number,))
    plt.close()
    print("Done ", number)

if __name__ == '__main__':
    df = pd.DataFrame({'A':[1,2,3],'B':[1,2,3]})
    df_array = df.values
    columns = df.columns.tolist()

    with Manager() as manager:
        # 创建共享数组
        shared_array = manager.list(df_array.tolist())
        # 初始化子进程,传递共享数据
        pool = Pool(4, initializer=init_worker, initargs=(shared_array, columns))
        pool.map(do_plot, range(4))

这种方法内存效率最高,但实现稍复杂,适合超大型数据集场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:05:19