加快python中的数组迭代时间

时间:2015-03-23 17:05:41

标签: python arrays numpy

目前我正在迭代一个数组,并且对于此数组中的每个值,我正在寻找在相应点周围区域内的另一个数组中的对应点处的最接近值。

总结:对于数组中的任何一点,您需要距离另一个数组中的对应点多远才能获得相同的值。

代码似乎适用于小型阵列,但我现在正在使用1024x768阵列,导致我每次运行都要等待很长时间....

任何帮助或建议都会非常感激,因为我已经有一段时间了!

格式Im的示例矩阵使用:np.array [[1,2],[3,4]]

#Distance to agreement

#Used later to define a region of pixels around a corresponding point
#to iterate over:
DTA = 26

#To account for noise in pixels - doesnt have to find the exact value,   
#just one within +/-130 of it.
limit = 130

#Containers for all pixel value matches and also the smallest distance
#to pixel match
Dist = []
Dist_min = []   

#Continer matrix for gamma pass/fail values
Dist_to_agree = np.zeros((i_size,j_size))

#i,j indexes the reference matrix (x), ii,jj indexes the measured     
#matrix(y). Finds a match within the limits, 
#appends the distance to the match into Dist.
#Then find the minimum distance to a match for that pixel and append it 
#to dist_min


for i, k in enumerate(x):
    for j, l in enumerate(k):
#added 10 packing to y matrix, so need to shift it by 10 in i&j
        for ii in range((i+10)-DTA,(i+10)+DTA):  
            for jj in range((j+10)-DTA,(j+10)+DTA):


#If the pixel value is within a range to account for noise, 
#let it be "found"
                if (y[ii,jj]-limit) <= x[i,j] <= (y[ii,jj]+limit):
                    #Calculating distance
                    dist_eu = sqrt(((i)-(ii))**2 + ((j) - (jj))**2)
                    Dist.append(dist_eu)

#If a value cannot be found within the noise range, 
#append 10 = instant fail. 
                else:
                    Dist.append(10)
        try:
            Dist_min.append(min(Dist))
            Dist_to_agree[i,j] = min(Dist)
        except ValueError:
            pass

        #Need to reset container or previous values will also be
        #accounted for when finding minimum
        Dist = []

print Dist_to_agree

4 个答案:

答案 0 :(得分:1)

首先,您要在xk中获取l的元素,然后将其丢弃并再次索引x。因此,代替x[i,j],您可以使用l,这会更快(尽管l不是一个非常有意义的名称,例如xi和{ {1}}可能会更好。)

其次,您正在重新计算xij和y [ii,jj] +限制y[ii,jj]-limit ym = y-limit every time. If you have enough memory, you can-precomputer these: yp = y + limit`。

第三,附加到列表比创建数组和设置长列表与长数组的值要慢。您还可以通过预先设置默认值来跳过整个and子句。

第四,您正在计算else两次,并且可能正在使用min(dist)版本而不是python版本,后者对于数组更快(这是制作的另一个原因) numpy和数组)。

但是,最大的加速是向内化两个循环。以下是我的测试,distx=np.random.random((10,10))

您的版本需要623毫秒。

这是我的版本,耗时7.6毫秒:

y=np.random.random((100,100))

答案 1 :(得分:1)

@Ciaran Meshgrid有点像两个嵌套循环的向量化等价物。以下是计算dist的两种等效方法。一个有循环,一个有meshgrid + numpy向量操作。第二个快6倍。

DTA=5
i=100
j=200

 def func1():
        dist1=np.zeros((DTA*2,DTA*2))
        for ii in range((i+10)-DTA,(i+10)+DTA):  
            for jj in range((j+10)-DTA,(j+10)+DTA):
                dist1[ii-((i+10)-DTA),jj-((j+10)-DTA)] =sqrt(((i)-(ii))**2 + ((j) - (jj))**2)
        return dist1

    def func2():
        dist2=np.zeros((DTA*2,DTA*2))
        ii, jj = meshgrid(np.arange((i+10)-DTA,(i+10)+DTA), 
                          np.arange((j+10)-DTA,(j+10)+DTA))
        dist2=np.sqrt((i-ii)**2+(j-jj)**2)
        return dist2

这是ii和jj矩阵在网格栅操作之后的样子

ii=
 [[105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]
 [105 106 107 108 109 110 111 112 113 114]]
jj= 
 [[205 205 205 205 205 205 205 205 205 205]
 [206 206 206 206 206 206 206 206 206 206]
 [207 207 207 207 207 207 207 207 207 207]
 [208 208 208 208 208 208 208 208 208 208]
 [209 209 209 209 209 209 209 209 209 209]
 [210 210 210 210 210 210 210 210 210 210]
 [211 211 211 211 211 211 211 211 211 211]
 [212 212 212 212 212 212 212 212 212 212]
 [213 213 213 213 213 213 213 213 213 213]
 [214 214 214 214 214 214 214 214 214 214]]

答案 2 :(得分:0)

for循环在纯python中非常慢,你有四个嵌套循环,这将非常慢。 Cython确实对for循环速度有所了解。您也可以尝试矢量化。虽然我不确定我是否完全理解你想要做什么,但你可能会尝试在最后的某些操作中进行矢量化。特别是最后两个循环。

因此,而不是两个ii,jj循环

y[ii,jj]-limit) <= x[i,j] <= (y[ii,jj]+limit)
你可以做点什么

ii, jj = meshgrid(np.arange((i+10)-DTA,(i+10)+DTA), np.arange((j+10)-DTA,(j+10)+DTA))
t=(y[(i+10)-DTA,(i+10)+DTA]-limit>=x[i,j]) & (y[(i+10)-DTA,(i+10)+DTA]+limit<=x[i,j])
Dist=np.sqrt((i-ii)**2)+(j-jj)**2))

np.min(Dist [t])将具有元素i的最小距离,j

答案 3 :(得分:-1)

numbapro编译器提供gpu加速。不幸的是它不是免费的。

http://docs.continuum.io/numbapro/