2014-11-05 119 views
2

我有一個二維numpy陣列input_array和兩個索引列表(x_coordsy_coords)。我喜歡爲每個x,y對以x,y座標爲中心切片3x3子陣列。最終結果將是一個3x3子陣列陣列,其中子陣列的數量等於我擁有的座標對的數量。從numpy數組按指數列表切片子陣列

最好避免for循環。目前我使用的生活步幅遊戲的變形從SciPy的食譜: http://wiki.scipy.org/Cookbook/GameOfLifeStrides

shape = (input_array.shape[0] - 2, input_array.shape[0] - 2, 3, 3) 
strides = input_array.strides + input_array.strides 
strided = np.lib.stride_trics.as_strided(input_array, shape=shape, strides=strides).\ 
    reshape(shape[0]*shape[1], shape[2], shape[3]) 

這產生了原始陣列的所有可能的3×3子陣列的(扁平)陣列的視圖。我再轉換的X,Y座標對能夠從strided選擇我想要的子陣:

coords = x_coords - 1 + (y_coords - 1)*shape[1] 
sub_arrays = strided[coords] 

雖然這工作完全正常,我不覺得這是一個有點麻煩。有沒有更直接的方法來做到這一點?此外,我希望將來可以擴展到3D案例。從nxmxk陣列切片nx3x3子陣列。這或許還可以使用大踏步但到目前爲止,我還沒有能夠使它在3D工作

回答

3

下面是使用陣列廣播的方法:

x = np.random.randint(1, 63, 10) 
y = np.random.randint(1, 63, 10) 

dy, dx = [grid.astype(int) for grid in np.mgrid[-1:1:3j, -1:1:3j]] 
Y = dy[None, :, :] + y[:, None, None] 
X = dx[None, :, :] + x[:, None, None] 

那麼可以使用a[Y, X]a選擇塊。下面是一個例子代碼:

img = np.zeros((64, 64)) 
img[Y, X] = 1 

這裏是圖由pyplot.imshow() ploted:

enter image description here

0

一個非常直接的解決方案將是一個列表理解和itertools.product

import itertools 

sub_arrays = [input_array[x-1:x+2, y-1:y+2] 
       for x, y in itertools.product(x_coords, y_coords)] 

這將創建所有可能的座標元組,然後從input_array中分割3x3陣列。 但這是一個for循環。而且你必須小心,x_coords和y_coords不在矩陣的邊界上。

+0

x_coords和y_coords預檢查,並在邊境的那些我離開了。另外,爲了得到想要的結果,我必須用'zip'替換'itertools.product'。 – xyzzyqed 2014-11-07 13:13:51