Skip to main content
 首页 » 编程设计

python之对于 Numpy 的循环速度

2025年05月04日17rubylouvre

我试图让这段代码在 python 中快速运行,但是我无法让它在接近它在 MATLAB 中运行的速度的任何地方运行。问题似乎是这个 for 循环,当数字“SRpixels”大约等于 25000 时,它需要大约 2 秒才能运行。

我似乎找不到任何方法来进一步减少它,我正在寻找建议。

下面的 numpy 数组的数据类型都是 float32,除了 **_Location[] 是 uint32。

for j in range (0,SRpixels): 
    #Skip data if outside valid range 
    if (abs(SR_pointCloud[j,0]) > SR_xMax or SR_pointCloud[j,2] > SR_zMax or SR_pointCloud[j,2] < 0): 
        pass 
    else:            
        RIGrid1_Location[j,0] = np.floor(((SR_pointCloud[j,0] + xPosition + 5) - xGrid1Center) / gridSize) 
        RIGrid1_Location[j,1] = np.floor(((SR_pointCloud[j,2] + yPosition) - yGrid1LowerBound) / gridSize) 
 
        RIGrid1_Count[RIGrid1_Location[j,0],RIGrid1_Location[j,1]] += 1 
        RIGrid1_Sum[RIGrid1_Location[j,0],RIGrid1_Location[j,1]] += SR_pointCloud[j,1] 
        RIGrid1_SumofSquares[RIGrid1_Location[j,0],RIGrid1_Location[j,1]] += SR_pointCloud[j,1] * SR_pointCloud[j,1] 
 
        RIGrid2_Location[j,0] = np.floor(((SR_pointCloud[j,0] + xPosition + 5) - xGrid2Center) / gridSize) 
        RIGrid2_Location[j,1] = np.floor(((SR_pointCloud[j,2] + yPosition) - yGrid2LowerBound) / gridSize) 
 
        RIGrid2_Count[RIGrid2_Location[j,0],RIGrid2_Location[j,1]] += 1  
        RIGrid2_Sum[RIGrid2_Location[j,0],RIGrid2_Location[j,1]] += SR_pointCloud[j,1] 
        RIGrid2_SumofSquares[RIGrid2_Location[j,0],RIGrid2_Location[j,1]] += SR_pointCloud[j,1] * SR_pointCloud[j,1] 

我确实尝试使用 Cython,我用 cdef int j 替换了 j 并编译了。没有明显的性能提升。有人有建议吗?

请您参考如下方法:

矢量化几乎总是加速 numpy 代码的最佳方式,而且其中大部分似乎是可矢量化的。例如,位置数组看起来很简单:

# these are all of your j values 
inds = np.arange(0,SRpixels) 
 
# these are the j values you don't want to skip 
sel = np.invert((abs(SR_pointCloud[inds,0]) > SR_xMax) | (SR_pointCloud[inds,2] > SR_zMax) | (SR_pointCloud[inds,2] < 0)) 
 
RIGrid1_Location[sel,0] = np.floor(((SR_pointCloud[sel,0] + xPosition + 5) - xGrid1Center) / gridSize) 
RIGrid1_Location[sel,1] = np.floor(((SR_pointCloud[sel,2] + yPosition) - yGrid1LowerBound) / gridSize) 
RIGrid2_Location[sel,0] = np.floor(((SR_pointCloud[sel,0] + xPosition + 5) - xGrid2Center) / gridSize) 
RIGrid2_Location[sel,1] = np.floor(((SR_pointCloud[sel,2] + yPosition) - yGrid2LowerBound) / gridSize) 

这没有 python 循环。

其余的比较棘手,将取决于您在做什么,但如果您以这种方式考虑它们,它们也应该是可向量化的。

如果您真的有一些东西不能矢量化并且必须用循环来完成——我只遇到过几次——我建议 Weave 而不是 Cython。它更难使用,但应该提供与 C 相当的速度。