2015-04-24 15 views
5

Nói rằng tôi có một mảng NumPy a, và tôi muốn tạo một mảng mới, bb[i, j] là một hàm của, nói:lọc tách trên mảng NumPy

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ều gì sẽ là cách nhanh nhất để làm điều này?

Vì đây là bộ lọc có thể tách rời, có cách nào để chạy điều này trong nhiều luồng không? (không phải quy trình, vì tôi sẽ phải sao chép dữ liệu trở lại)

Hoặc đang viết mã C để bỏ qua GIL bắt buộc?

Các giải pháp một phần (như giả định hàm là tuyến tính) cũng được chào đón.

+0

Bạn có ý nghĩa như cửa sổ cuộn/di chuyển hay bộ lọc? ví dụ trong liên kết này là tổng kết cho một cửa sổ 3x3 qua một mảng 2D http://www.johnvinyard.com/blog/?p=268 –

+0

Âm thanh giống như một số câu hỏi SO khác, hầu hết sử dụng thuật ngữ 'cửa sổ trượt '(hoặc di chuyển). Mặc dù hầu hết tập trung vào việc lặp qua cửa sổ, không phải là việc chia nhỏ nhiệm vụ giữa các chủ đề hoặc quy trình. – hpaulj

Trả lời

1

Một lý tưởng numpy cách làm việc với một cửa sổ trượt như thế này là để xây dựng một mảng 4D

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

nơi

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

và viết chức năng của bạn làm một số loại giảm về cuối cùng 2 kích thước. sum hoặc mean sẽ là điển hình, ví dụ:

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

Câu hỏi SO khác cho thấy cách sử dụng np.lib.stride_tricks.as_strided để tạo mảng như vậy. Nhưng chỉ với một mảng con 3x3, nó có thể là cũng nhanh để làm một cái gì đó giống như

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

(hoặc sử dụng hstackvstack để tác dụng tương tự).

Nhưng một điều tốt đẹp (hoặc có lẽ không tốt đẹp) về cách tiếp cận có sức cản là nó không liên quan đến việc sao chép bất kỳ dữ liệu nào của a - đó chỉ là một chế độ xem.

Để chia công việc thành nhiều phần, tôi có thể tưởng tượng bằng cách sử dụng các lát C (trên thứ nguyên thứ nhất 2), ví dụ:

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