Cela peut être fait plus rapidement, en remodelant et en échangeant les axes, puis en répétant sur tous les éléments du noyau, comme ceci :
im = np.arange(81).reshape(9,9)
print np.swapaxes(im.reshape(3,3,3,-1),1,2)
Vous obtenez ainsi un tableau de 3*3 tuiles qui s'étend sur toute la surface :
[[[[ 0 1 2] [[ 3 4 5] [[ 6 7 8]
[ 9 10 11] [12 13 14] [15 16 17]
[18 19 20]] [21 22 23]] [24 25 26]]]
[[[27 28 29] [[30 31 32] [[33 34 35]
[36 37 38] [39 40 41] [42 43 44]
[45 46 47]] [48 49 50]] [51 52 53]]]
[[[54 55 56] [[57 58 59] [[60 61 62]
[63 64 65] [66 67 68] [69 70 71]
[72 73 74]] [75 76 77]] [78 79 80]]]]
Pour obtenir les tuiles qui se chevauchent, nous devons répéter cette opération 8 fois de plus, mais en "enveloppant" le tableau, en utilisant une combinaison de vstack
y column_stack
. Notez que les tableaux de tuiles de droite et de fond s'enroulent (ce qui peut ou non être ce que vous voulez, selon la façon dont vous traitez les conditions de bord) :
im = np.vstack((im[1:],im[0]))
im = np.column_stack((im[:,1:],im[:,0]))
print np.swapaxes(im.reshape(3,3,3,-1),1,2)
#Output:
[[[[10 11 12] [[13 14 15] [[16 17 9]
[19 20 21] [22 23 24] [25 26 18]
[28 29 30]] [31 32 33]] [34 35 27]]]
[[[37 38 39] [[40 41 42] [[43 44 36]
[46 47 48] [49 50 51] [52 53 45]
[55 56 57]] [58 59 60]] [61 62 54]]]
[[[64 65 66] [[67 68 69] [[70 71 63]
[73 74 75] [76 77 78] [79 80 72]
[ 1 2 3]] [ 4 5 6]] [ 7 8 0]]]]
En procédant de cette manière, vous vous retrouvez avec 9 ensembles de tableaux, et vous devez donc les reconnecter. Ceci, et tout le remodelage, se généralise à ceci (pour les tableaux dont les dimensions sont divisibles par 3) :
def new(im):
rows,cols = im.shape
final = np.zeros((rows, cols, 3, 3))
for x in (0,1,2):
for y in (0,1,2):
im1 = np.vstack((im[x:],im[:x]))
im1 = np.column_stack((im1[:,y:],im1[:,:y]))
final[x::3,y::3] = np.swapaxes(im1.reshape(rows/3,3,cols/3,-1),1,2)
return final
En comparant cette new
pour parcourir en boucle toutes les tranches (ci-dessous), en utilisant la fonction timeit
Pour un tableau de 300*300, c'est environ 4 fois plus rapide.
def old(im):
rows,cols = im.shape
s = []
for x in xrange(1,rows):
for y in xrange(1,cols):
s.append(im[x-1:x+2,y-1:y+2])
return s