2015-04-24 3 views
5

Sagen, ich habe eine numpy Array a, und ich möchte ein neues Array erstellen, b so dass b[i, j] ist eine Funktion von, sagen:separierbarkeit auf numpy Array

a[i-1, j-1], a[i-1, j ], a[i-1, j+1], 
a[i , j-1], a[i , j ], a[i , j+1], 
a[i+1, j-1], a[i+1, j ], a[i+1, j+1] 

Was ist der schnellste Weg sein würde, um dies zu tun?

Da dies ein separierbarer Filter ist, gibt es eine Möglichkeit, dies in mehreren Threads auszuführen? (nicht Prozesse, weil ich die Daten zurück kopieren müsste)

Oder schreibt C-Code um die GIL zu umgehen obligatorisch?

Teillösungen (wie die Annahme der Funktion ist linear) sind auch willkommen.

+0

Meinst du wie ein rollendes/bewegliches Fenster oder Filter? das Beispiel in diesem Link ist für eine Summierung für ein 3x3-Fenster über ein 2D-Array http://www.johnvinyard.com/blog/?p=268 –

+0

Klingt wie eine Reihe von anderen SO-Fragen, die meisten mit dem Begriff "Schiebefenster '(oder sich bewegen). Obwohl sich die meisten darauf konzentrieren, über das Fenster zu iterieren, nicht die Aufgabe unter Threads oder Prozessen aufzuteilen. – hpaulj

Antwort

1

Eine idealisierte numpy Weise wie dies mit einem Schiebefenster arbeitet, ist ein 4D-Array

C.shape = (N,M,3,3) 

wo

C[i,j,:,:] = np.array([a[i-1, j-1], a[i-1, j ], a[i-1, j+1], 
         a[i , j-1], a[i , j ], a[i , j+1], 
         a[i+1, j-1], a[i+1, j ], a[i+1, j+1]]) 

und schreiben Sie Ihre Funktion auf der letzten 2 eine Art von Reduktion tun zu konstruieren Maße. sum oder mean wäre typisch, z.B.

B = C.sum(axis=(2,3)) 

Andere SO Fragen zeigen, wie np.lib.stride_tricks.as_strided zu verwenden, wie ein Array zu konstruieren. Aber nur mit einem 3x3-Subarray, könnte es genauso schnell sein, etwas zu tun, wie

C = np.zeros((N,M,3,3)) 
C[:,:,0,0] = a[:-1,:-1] 
etc. 

(oder verwenden Sie hstack und vstack auf den gleichen Effekt).

Aber eine nette Sache (oder vielleicht nicht so nett) über den schrittweisen Ansatz ist, dass es keine Daten von a kopieren - es ist nur eine Ansicht.

Um den Job in Stücke zu teilen, kann ich mir vorstellen, Scheiben von (auf den ersten 2 Dimensionen), z.

C[0:100,0:100,:,:].sum(axis=(2,3))