Python 在嵌套循环中加速numpy计算

Python 在嵌套循环中加速numpy计算,python,numpy,Python,Numpy,下面是一些代码片段 def径向基函数(r): rsq=r**2.0 如果rsq==0.0: 返回0.0 val=rsq*np.log(rsq) 如果np.isnan(val): 返回0.0 返回值 对于范围内的i(449): 对于j,枚举(p)中的行: res[j]+=w[i]*rbf(r=np.linalg.norm(p[i]-row)) 返回res 这里,p表示具有形状的数组(4448^2,3),res表示具有形状的数组(4448^2,3)。这种就地添加的过程消耗了太多的时间。我试了另一种

下面是一些代码片段

def径向基函数(r):
rsq=r**2.0
如果rsq==0.0:
返回0.0
val=rsq*np.log(rsq)
如果np.isnan(val):
返回0.0
返回值
对于范围内的i(449):
对于j,枚举(p)中的行:
res[j]+=w[i]*rbf(r=np.linalg.norm(p[i]-row))
返回res
这里,
p
表示具有形状的数组(4448^2,3),
res
表示具有形状的数组(4448^2,3)。这种就地添加的过程消耗了太多的时间。我试了另一种方法如下

def径向基函数(r):
rsq=r**2.0
如果rsq==0.0:
返回0.0
val=rsq*np.log(rsq)
如果np.isnan(val):
返回0.0
返回值
def func(元素,行):
总和=总和([w[j]
*径向基函数(r=np.linalg.norm(p[j]-行))
对于范围(449)]内的j)
返回和+元素
dst_res=np.array([func(elem=elem,row=row)
对于元素,行在zip中(res,p)])
返回dst_res

但我仍然没有看到任何进展。有什么提高性能的建议吗?

有几种方法可以加快程序的速度

首先,我将重新构造计算函数:避免ifs或尝试将它们放在最外层的循环中,避免计算密集型函数,如power(**)

第二:增加的速度相对较快,通过改进这一点不会有多大收获。您可能应该尝试将数据矢量化以加快乘法:

tmp = np.zeros(449) # store values in temporary vector 
for j, row in enumerate(p): # change order of the loop 
    for i in range(449):
        tmp[i] = rbf(r=np.linalg.norm(p[i] - row)) # fill vector
    #the NaN-Check should be actually made here: measure both scenarios
    tmp[np.isnan(tmp)] = 0.0
    
    res[j] = sum( w * tmp)
return res
您可以进一步降低成本:

tmp = np.zeros(449) # store values in temporary vector 
for j, row in enumerate(p): # change order of the loop 
    for i in range(449):
        tmp[i] = rbf(r=np.linalg.norm(p[i] - row)) # fill vector 
    tmp *= tmp #rbf part 1
    tmp *= np.log(tmp) # rbf part 2
    tmp[np.isnan(tmp)] = 0.0 # NaN-Testing
    
    res[j] = sum( w * tmp) #sum
return res

这些代码片段未经测试。可能会有进一步的改进。始终检查答案是否仍然正确。请分享您的进展。

什么是
w
?您能否将其表示为带有输入(
w
p
?)和输出的纯函数?为什么
449
?这与
4448^2
有什么关系?请提供一个适当的MCVE,可以在终端中运行,无需额外键入。
tmp = np.zeros(449) # store values in temporary vector 
for j, row in enumerate(p): # change order of the loop 
    for i in range(449):
        tmp[i] = rbf(r=np.linalg.norm(p[i] - row)) # fill vector 
    tmp *= tmp #rbf part 1
    tmp *= np.log(tmp) # rbf part 2
    tmp[np.isnan(tmp)] = 0.0 # NaN-Testing
    
    res[j] = sum( w * tmp) #sum
return res