Skip to main content
 首页 » 编程设计

python之向量化嵌套的 for 循环 Python

2025年05月04日15jyk

我有一个正在迭代的 numpy 数组:

import numpy 
import math 
array = numpy.array([[1, 1, 2, 8, 2, 2], 
               [5, 5, 4, 1, 3, 2], 
               [5, 5, 4, 1, 3, 2], 
               [5, 5, 4, 1, 3, 2], 
               [9, 5, 8, 8, 2, 2], 
               [7, 3, 6, 6, 2, 2]]) 
 
 
Pixels = ['U','D','R','L','UL','DL','UR','DR'] 
 
for i in range (1,array.shape[0]-1): 
    for j in range (1,array.shape[1]-1): 
 
 
         list = [] 
         while len(list) < 2: 
                iToMakeList = i 
                jToMakeList = j 
 
                if iToMakeList > array.shape[0]-1 or iToMakeList < 1 or jToMakeList> array.shape[0]-1 or jToMakeList < 1: 
 
                    break 
 
                PixelCoord = { 
            'U' : (iToMakeList-1,jToMakeList), 
            'D' : (iToMakeList+1,jToMakeList), 
            'R' : (iToMakeList,jToMakeList+1), 
            'L' : (iToMakeList,jToMakeList-1), 
            'UL' : (iToMakeList-1,jToMakeList-1), 
            'DL' : (iToMakeList+1,jToMakeList-1), 
            'UR' : (iToMakeList-1,jToMakeList+1), 
            'DR' : (iToMakeList+1,jToMakeList+1) 
                } 
                Value = { 
            'U' : array[iToMakeList-1][jToMakeList], 
            'D' : array[iToMakeList+1][jToMakeList], 
            'R' : array[iToMakeList][jToMakeList+1], 
            'L' : array[iToMakeList][jToMakeList-1], 
            'UL' : array[iToMakeList-1][jToMakeList-1], 
            'DL' : array[iToMakeList+1][jToMakeList-1], 
            'UR' : array[iToMakeList-1][jToMakeList+1], 
            'DR' : array[iToMakeList+1][jToMakeList+1] 
                } 
 
 
                candidates = [] 
                for pixel in Pixels: 
                    candidates.append((Value[pixel],pixel)) 
 
                Lightest = max(candidates) 
 
 
                list.append(PixelCoord[Lightest[1]]) 
 
                iToMakeList = PixelCoord[Lightest[1]][0] 
                jToMakeList = PixelCoord[Lightest[1]][1] 

我想加快这个过程。这很慢。

假设此代码段的输出是我的最终目标,而我唯一想做的就是加速此代码。

请您参考如下方法:

为了使您的问题对我有意义,我认为您需要移动 list = [] 出现的位置。否则,在 list 已满之前,您永远无法访问 i=0、j=1。我无法想象它会像当前实现的那样慢——列表很快就会满,然后 for 循环应该很快。这就是我相信你的意图。如果这不正确,请澄清。

for i in range (0,array.shape[0]): 
    for j in range (0,array.shape[1]): 
         list = [] 
         while len(list) < 100: 
                print "identity", i, j 
 
                #find neighboring entry with greatest value (e.g., assume it is [i-1, j] with value 10) 
                list.append((i-1,j)) 
                i = i-1 
                j = j 
         #perform operations on list 

让我们做一些修改。我假设有一个函数 get_max_nbr(i,j) 返回最大邻居的坐标。您的代码速度较慢的地方之一是它会多次调用 get_max_nbr 以获得相同的坐标(在循环的每个步骤中它都会调用 100 次)。下面的代码使用 memoization解决这个问题(平均减少到 1 次)。因此,如果这是您的瓶颈,这应该能让您获得接近 100 倍的加速。

maxnbr = {} 
for i in range(0,array.shape[0]): 
    for j in range (0,array.shape[1]): 
        list = [] 
        current_loc = (i,j) 
        while len(list) < 100: 
            if current_loc not in maxnbr:  #if this is our first time seeing current_loc 
                maxnbr[current_loc] = get_max_nbr(*current_loc) #note func(*(i,j)) becomes func(i,j) 
            current_loc = maxnbr[current_loc] 
            list.append(current_loc) 
        #process list here                  

这并没有成功矢量化,但它确实创建了您想要的列表(我认为),这应该是一个重大改进。可能是如果我们对列表处理了解得更多,我们也许能够找到更好的方法,但目前还不清楚。