我试图让这段代码在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并进行了编译。没有明显的性能提升。有人有建议吗?
答案 0 :(得分:5)
矢量化几乎总是加速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 over Cython。它更难使用,但应该提供与C相当的速度。
答案 1 :(得分:1)
首先尝试向量化计算,如果必须逐个元素进行计算,这里有一些加速提示:
使用NumPy标量计算比内置标量慢得多。 array [i,j]将得到一个numpy标量,array.item(i,j)将返回一个内置标量。
在进行标量计算时,数学模块中的函数比numpy快。
以下是一个例子:
import numpy as np
import math
a = np.array([[1.1, 2.2, 3.3],[4.4, 5.5, 6.6]])
%timeit np.floor(a[0,0]*2)
%timeit math.floor(a[0,0]*2)
%timeit np.floor(a.item(0,0)*2)
%timeit math.floor(a.item(0,0)*2)
输出:
100000 loops, best of 3: 10.2 µs per loop
100000 loops, best of 3: 3.49 µs per loop
100000 loops, best of 3: 6.49 µs per loop
1000000 loops, best of 3: 851 ns per loop
所以将np.floor
更改为math.floor
,将SR_pointCloud[j,0]
更改为SR_pointCloud.item(j,0)
会加快循环速度。