Numpy 提高循环性能的速度

Numpy 提高循环性能的速度,numpy,scipy,multiprocessing,cython,pymc,Numpy,Scipy,Multiprocessing,Cython,Pymc,我正在尝试使用pyMC为我的马尔可夫链蒙特卡罗代码构建一个示例。因此,对于模型的采样参数,每次通过调用nfw class中的getLensing实例构建输出,并与观测数据进行比较。我的问题是,我的代码在计算模型参数时非常慢。例如,我有24000个数据点,然后对于每一个数据点,我都有一个概率分布——例如,obj_pdf——我将其边缘化(集成)在内部循环中。因此,每次计算模型的所有输出至少需要一个小时 import numpy as np z=np.arange(0,1.5,0.001) z_h=0

我正在尝试使用pyMC为我的马尔可夫链蒙特卡罗代码构建一个示例。因此,对于模型的采样参数,每次通过调用nfw class中的
getLensing
实例构建输出,并与观测数据进行比较。我的问题是,我的代码在计算模型参数时非常慢。例如,我有24000个数据点,然后对于每一个数据点,我都有一个概率分布——例如,
obj_pdf
——我将其边缘化(集成)在内部循环中。因此,每次计算模型的所有输出至少需要一个小时

import numpy as np
z=np.arange(0,1.5,0.001)
z_h=0.15
for j in range(pos.shape[0]):
    value1=0;value2=0
    pdf=obj_pdf[j,:]/sum(obj_pdf[j,:])
    for i in range(len(z)):
        if (z[i]>z_h) :
        g1,g2=nfw.getLensing( pos[j,:], z[i])
            value1+=g1*pdf[i]
            value2+=g2*pdf[i]
    if (j<1):
       value=np.array([value1,value2])
    else:
       value=np.vstack((value, np.array([value1,value2]))) 

下面是一些代码。如果时间从60分钟到59分钟,我会感到惊讶

import numpy as np
z_h=0.15
z=np.arange(z_h, 1.5,0.001) #start the range from what you need (not exactly
z=z[1:] # needed because you said if (z[i]>z_h), range gives (z[i]>=z_h)

value=np.array([])

for j in range(pos.shape[0]):
    value1=0;value2=0
    pdf=obj_pdf[j,:]/sum(obj_pdf[j,:])
    posj=pos[j,:] #precalculate 
    for i,zi in enumerate(z): #use enumerate if you need value and index
        g1,g2=nfw.getLensing( posj, zi)
        value1+=g1*pdf[i]
        value2+=g2*pdf[i]
    value=np.append(value, np.array([value1,value2])) # use a proper append function
和其他人一样,我假设getLensing正在消耗您的CPU周期


根据的第一个答案,np.vectorize不会加快函数的速度。

您的代码大部分时间是在循环中调用的函数中,还是真的在执行循环指令?如果是前者,那么Python的循环性能就不是瓶颈。为了正确识别瓶颈,您需要分析代码并查看大部分时间花在哪些内部函数上。对代码运行分析程序以查看函数的
tottime
python-mcprofile myprogram.py
@Jan PhilipGehrcke我想我的大部分时间都花在了对pdf进行集成上,这使得集成速度非常慢。但是,调用的另一个函数也是一个单独的类,也在内部循环中调用。@Jan PhilipGehrcke,如果我用例如
numpy.vectorize
替换内部循环,则增加代码?配置文件的速度!!不要说你认为它把你的大部分时间都花在了X上,只要在分析器中运行你的代码就行了!这是了解瓶颈实际位置的一种既便宜又简单的方法。按照@woot的指示去做。就像我说的,我没想到会这样。你的问题会越来越严重。
import numpy as np
z_h=0.15
z=np.arange(z_h, 1.5,0.001) #start the range from what you need (not exactly
z=z[1:] # needed because you said if (z[i]>z_h), range gives (z[i]>=z_h)

value=np.array([])

for j in range(pos.shape[0]):
    value1=0;value2=0
    pdf=obj_pdf[j,:]/sum(obj_pdf[j,:])
    posj=pos[j,:] #precalculate 
    for i,zi in enumerate(z): #use enumerate if you need value and index
        g1,g2=nfw.getLensing( posj, zi)
        value1+=g1*pdf[i]
        value2+=g2*pdf[i]
    value=np.append(value, np.array([value1,value2])) # use a proper append function