2015-04-24 23 views
5

Say Mam tablicy numpy a i chcę, aby utworzyć nową tablicę, b takie, że b[i, j] jest funkcją, powiedzieć:wtykowy filtr na numpy tablicy

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] 

Jaki byłby najszybszym sposobem to zrobić?

Ponieważ jest to filtr separowalny, czy istnieje sposób na uruchomienie go w wielu wątkach? (nie procesy, ponieważ musiałbym skopiować dane z powrotem)

Lub pisze kod C, aby ominąć GIL obowiązkowe?

Częściowe rozwiązania (jak zakładanie, że funkcja jest liniowa) również są mile widziane.

+0

Czy chodzi ci o rolkę/ruchome okno lub filtr? przykład w tym łączu jest dla sumowania dla okna 3x3 na tablicy 2D http://www.johnvinyard.com/blog/?p=268 –

+0

Brzmi jak wiele innych pytań SO, najczęściej używając terminu 'przesuwane okna '(lub przenoszenie). Chociaż większość skupia się na iteracji przez okno, a nie na dzieleniu zadania pomiędzy wątki lub procesy. – hpaulj

Odpowiedz

1

wyidealizowanej numpy sposób pracy z przesuwnym oknem, jak to jest skonstruowanie 4D tablicę

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

gdzie

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]]) 

i napisać funkcja zrobić jakąś redukcję na ostatni 2 wymiary. sum lub mean byłyby typowe, np.

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

Inne SO pytania pokazują, jak korzystać np.lib.stride_tricks.as_strided skonstruować taką tablicę. Ale tylko z subarray 3x3, to może być tak samo szybko coś zrobić jak

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

(lub użyć hstack i vstack do tego samego skutku).

Ale fajną rzeczą (a może nie tak miłą) jest to, że nie wymaga ona kopiowania żadnych danych z a - to tylko widok.

Jeśli chodzi o dzielenie pracy na części, mogę sobie wyobrazić użycie plasterków C (w 1. 2 wymiarach), np.

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