2013-07-09 20 views
7

Ich möchte die Dimensionen meiner numpy Array neu anordnen. Das folgende Stück Code funktioniert, aber es ist zu langsam.Neuanordnung von numpy Arrays

for i in range(image_size): 
    for j in range(image_size): 
     for k in range(3): 
      new_im[k, i, j] = im[i, j, k] 

Nach diesem vektorisiert ich die new_im:

new_im_vec = new_im.reshape(image_size**2 * 3) 

Das heißt, ich habe nicht new_im brauchen und ich brauche nur zu new_im_vec bekommen. Gibt es einen besseren Weg, dies zu tun? image_size ist etwa 256.

+0

Wenn Sie Python2 verwenden, können Sie 'xrange' anstelle von' range' – jh314

Antwort

10

Check out rollaxis, eine Funktion, die die Achsen um verschiebt, so dass Sie Ihre Array in einem einzigen Befehl neu zu ordnen. Wenn im Form hat i, j, k

rollaxis(im, 2) 

ein Array mit Form k zurückkehren sollte, i, j.

Danach können Sie Ihr Array abflachen, ravel ist eine klare Funktion für diesen Zweck. Putting all dies zusammen, Sie haben einen schönen Einzeiler:

new_im_vec = ravel(rollaxis(im, 2)) 
+0

Cool! Es klappt. Die andere Sache, die ich tun muss, ist in der ersten Dimension zu spiegeln. Tausche a [1,:,:] und a [3,:,:]. Gibt es dafür eine Funktion? –

+1

@Mohammad Moghimi, Wenn ich Ihre Frage richtig verstanden habe, können Sie flipud verwenden, um das Array um die horizontale Achse zu drehen. a [:: - 1,:,:] sollte auch funktionieren. –

+2

+1 Wahrscheinlich die beste Option. Der Vollständigkeit halber gibt es auch die Option (die, wie ich glaube, von 'np.rollaxis' genannt wird), 'np.transpose (im, (2, 0, 1))' zu machen. Als Nebenbemerkung geben 'np.rollaxis' oder' np.transpose' eine Ansicht der Originaldaten zurück, aber wenn in dieser Ansicht ein flacher Aufruf erfolgt, wird wahrscheinlich eine Kopie ausgelöst. – Jaime

7
new_im = im.swapaxes(0,2).swapaxes(1,2) # First swap i and k, then i and j 
new_im_vec = new_im.flatten() # Vectorize 

Dies sollte viel schneller sein, weil swapaxes auf dem Array eine Ansicht zurückgibt, anstatt Elemente Kopieren über.

Und natürlich, wenn Sie new_im überspringen möchten, können Sie es in einer Zeile tun, und immer noch nur flatten macht kopieren.

new_im_vec = im.swapaxes(0,2).swapaxes(1,2).flatten()