【问题标题】:Parallel processing with Python class object使用 Python 类对象进行并行处理
【发布时间】:2017-04-10 09:30:08
【问题描述】:

我在 Python 中有一个 for 循环,其中包含优化函数 scipy.optimize.root。函数outputs是一个描述优化结果的类对象(称为sol):

import numpy as np           
import scipy.optimize as so

def root2d(x,a,b):
   F1 = np.exp(-np.exp(-(x[0]+x[1]))) - x[1]*(b+x[0]**2)
   F2 = x[0]*np.cos(x[1]) + x[1]*np.sin(x[0]) - a
   return (F1,F2)

x0 = np.array([0.1,0.1]) # initial guess
alist = np.linspace(-0.5,-0.3,10)
blist = np.linspace(0.2,0.3,10)

xlist = np.zeros(10)
ylist = np.zeros(10)
zlist = np.zeros(10)

for jj in range(0,10):

    a = alist[jj]
    b = blist[jj]

    sol = so.root(root2d,x0,args=(a,b),method='lm',tol=1e-9)

    xlist[jj] = sol.x[0] # optimised value
    ylist[jj] = sol.x[1] # optimised value
    zlist[jj] = sol.success # was solver successful?

# do something with xlist ylist zlist

现在我正在尝试使用this post 中的建议并行化for 循环。但是我不确定如何处理sol 输出以及如何编写上面的for 循环以便可以在这种结构中使用它:

from multiprocessing import Pool

p = Pool(4)
xlist,ylist,zlist = zip(*p.map(so.root,range(0,10)))

这是诺伦皇室的回答。

编辑:我想在可用 Python 模块为 numpy、scipy、matplotlib、cython 和 mpi4py 的 HPC 集群上运行我的程序(没有这个 MWE)。尽管有许多方法可以进行并行处理,但我想对现有(串行 for 循环)代码进行最小的更改。

【问题讨论】:

    标签: python numpy optimization parallel-processing scipy


    【解决方案1】:

    要使用Pool,您通常提供一个函数并在其上调用Pool.map

    在你的情况下:

    from multiprocessing import Pool
    
    def run(jj):
        import scipy.optimize as so
    
        a = alist[jj]
        b = blist[jj]
    
        sol = so.root(root2d,x0,args=(a,b),method='lm',tol=1e-9)
    
        return sol.x[0], sol.x[1], sol.success
    
    
    if __name__ == '__main__':
    
        # your declarations go here ...
    
        p = Pool(4)
        result = p.map(run, range(0,10))
    

    ...它为您提供包含解决方案的元组列表...

    【讨论】:

    • 应该x0alistblistrun(jj) 函数内吗?我假设xlist = ylist = zlist = np.zeros(10) 应该在p=Pool(4) 之前
    • 不。所有这些定义,包括root2d 的函数定义都放在我放置# your declarations go here的地方
    • 奇怪...当我这样做时,我得到一个错误:AttributeError: module '__main__' has no attribute '__spec__'
    • 您使用的是哪个版本的python?对我(Python3)来说,这段代码运行没有错误......您是否如上所述在if __name__ == '__main__' 内创建了池(p = Pool(4))?你把import numpy as np放在哪里了?
    • Python 3.5.2 64 位。是的,我在if __name__ == '__main__' 中创建了并行池。 import numpy as np 在我导入 multiprocessing 之前出现。
    【解决方案2】:

    由于某种原因,Tw UxTLi51Nus 帖子中给出的代码似乎不适用于 Python 3.5.2。做了一些改动,下面的代码看起来就ok了……

    import numpy as np 
    import scipy.optimize as so
    from multiprocessing import Pool
    
    def root2d(x,a,b):
        F1 = np.exp(-np.exp(-(x[0]+x[1]))) - x[1]*(b+x[0]**2)
        F2 = x[0]*np.cos(x[1]) + x[1]*np.sin(x[0]) - a
        return (F1,F2)
    
    def run(jj):
    
        x0 = np.array([0.1,0.1]) # initial guess
        alist = np.linspace(-0.5,-0.3,10)
        blist = np.linspace(0.2,0.3,10)
    
        a = alist[jj]
        b = blist[jj]
    
        sol = so.root(root2d,x0,args=(a,b),method='lm',tol=1e-9)
    
        return sol.x[0], sol.x[1], sol.success
    
    
    if __name__ == '__main__':
    
        xlist = np.zeros(10)
        ylist = np.zeros(10)
        zlist = np.zeros(10)
    
        p = Pool(4)
        result = p.map(run, range(0,10))
        print(result)
    

    我不得不将迭代值 alistblist 和初始猜测 x0 放入 run 函数中。这些被输入scipy.optimize.root 求解器。我这样做时没有错误,解决方案是:

    [(-0.53888782445459149, 0.043495493090149454, True),
     (-0.52328348126598456, 0.032937536902490253, True), 
     (-0.50743370799474086, 0.022462155879391384, True), 
     (-0.49135105437855231, 0.01203948230426068, True), 
     (-0.47502920008575156, 0.001732198125265777, True), 
     (-0.45846822054716679, -0.0084225504551842089, True), 
     (-0.4416527225847745, -0.018336039419045602, True), 
     (-0.42455931996843449, -0.027893297385455082, True), 
     (-0.40720848051853215, -0.037005663686040566, True), 
     (-0.38955545334271019, -0.045486751099290013, True)]
    

    【讨论】:

    • 好吧,我不明白为什么会有这种差异,在我的系统上,当 x0alistblistxlist 和 @ 的声明之间声明时,它运行得非常好987654332@
    • 您甚至可以删除xlistylistzlist 的声明,因为结果现在在result BTW 中
    猜你喜欢
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多