我试图让这段代码在 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 相当的速度。
