2015-07-20 2 views
4

У меня есть 2-D Numpy массив следующим образом:Извлечение блоков или пластыри из массива NumPy

a = np.array([[1,5,9,13], 
       [2,6,10,14], 
       [3,7,11,15], 
       [4,8,12,16]] 

Я хочу, чтобы извлечь его в участки 2 с помощью 2-х размеров с повторением из элементов.

Ответ должен быть точно таким же. Это может быть 3-D массив или список с тем же порядком элементов, как показано ниже:

[[[1,5], 
[2,6]], 

[[3,7], 
[4,8]], 

[[9,13], 
[10,14]], 

[[11,15], 
[12,16]]] 

Как сделать это легко?

В моей реальной проблеме размер a (36, 72). Я не могу сделать это один за другим. Я хочу программный способ сделать это.

+0

Я обновил свой ответ на http://stackoverflow.com/ вопросы/26871083/как-кан-я-векторизовать--усреднение по-2х2-подмассивов-оф-Numpy массива /. Учитывая этот вопрос и http://stackoverflow.com/questions/31494190/elements-arrangement-for-calculating-mean-in-python-numpy, я думаю, мы можем закрыть это как обман. –

+0

@WarrenWeckesser Можете ли вы показать мне ЗДЕСЬ, как бы вы извлекали патчи, когда я извлекал из себя mannually в моем вопросе? – Borys

+0

@WarrenWeckesser Это не о вычислении среднего значения, как в ответе oyur – Borys

ответ

1

Вот довольно загадочный NumPy один вкладыш для создания своего 3-D массива, называемого result1 здесь:

In [60]: x 
Out[60]: 
array([[2, 1, 2, 2, 0, 2, 2, 1, 3, 2], 
     [3, 1, 2, 1, 0, 1, 2, 3, 1, 0], 
     [2, 0, 3, 1, 3, 2, 1, 0, 0, 0], 
     [0, 1, 3, 3, 2, 0, 3, 2, 0, 3], 
     [0, 1, 0, 3, 1, 3, 0, 0, 0, 2], 
     [1, 1, 2, 2, 3, 2, 1, 0, 0, 3], 
     [2, 1, 0, 3, 2, 2, 2, 2, 1, 2], 
     [0, 3, 3, 3, 1, 0, 2, 0, 2, 1]]) 

In [61]: result1 = x.reshape(x.shape[0]/2, 2, x.shape[1]/2, 2).swapaxes(1, 2).reshape(-1, 2, 2) 

result1 подобен 1-й массивом 2-й массивов:

In [68]: result1.shape 
Out[68]: (20, 2, 2) 

In [69]: result1[0] 
Out[69]: 
array([[2, 1], 
     [3, 1]]) 

In [70]: result1[1] 
Out[70]: 
array([[2, 2], 
     [2, 1]]) 

In [71]: result1[5] 
Out[71]: 
array([[2, 0], 
     [0, 1]]) 

In [72]: result1[-1] 
Out[72]: 
array([[1, 2], 
     [2, 1]]) 

(К сожалению, на данный момент у меня нет времени, чтобы подробно рассказать о том, как это работает. Возможно, позже ...)

Ниже приведена менее загадочная версия, в которой используется nes понимание. В этом случае result2 список питон 2-й Numpy массивов:

In [73]: result2 = [x[2*j:2*j+2, 2*k:2*k+2] for j in range(x.shape[0]/2) for k in range(x.shape[1]/2)] 

In [74]: result2[5] 
Out[74]: 
array([[2, 0], 
     [0, 1]]) 

In [75]: result2[-1] 
Out[75]: 
array([[1, 2], 
     [2, 1]]) 
+0

Спасибо, это то, что я искал! – Borys

3

Вы можете достичь его с помощью комбинации np.reshape и np.swapaxes как так -

def extract_blocks(a, blocksize): 
    M,N = a.shape 
    b0, b1 = blocksize 
    return a.reshape(M//b0,b0,N//b1,b1).swapaxes(1,2).reshape(-1,b0,b1) 

случаев Примеров

Давайте используем образец входного массива, например:

In [94]: a 
Out[94]: 
array([[2, 2, 6, 1, 3, 6], 
     [1, 0, 1, 0, 0, 3], 
     [4, 0, 0, 4, 1, 7], 
     [3, 2, 4, 7, 2, 4], 
     [8, 0, 7, 3, 4, 6], 
     [1, 5, 6, 2, 1, 8]]) 

Теперь давайте использовать некоторые размеры блока для тестирования. Давайте используем два случая с блоками размером (2,3) и (3,3).

Дело № 1:

In [95]: extract_blocks(a, (2,3)) # Blocksize : (2,3) 
Out[95]: 
array([[[2, 2, 6], 
     [1, 0, 1]], 

     [[1, 3, 6], 
     [0, 0, 3]], 

     [[4, 0, 0], 
     [3, 2, 4]], 

     [[4, 1, 7], 
     [7, 2, 4]], 

     [[8, 0, 7], 
     [1, 5, 6]], 

     [[3, 4, 6], 
     [2, 1, 8]]]) 

Дело № 2:

In [96]: extract_blocks(a, (3,3)) # Blocksize : (3,3) 
Out[96]: 
array([[[2, 2, 6], 
     [1, 0, 1], 
     [4, 0, 0]], 

     [[1, 3, 6], 
     [0, 0, 3], 
     [4, 1, 7]], 

     [[3, 2, 4], 
     [8, 0, 7], 
     [1, 5, 6]], 

     [[7, 2, 4], 
     [3, 4, 6], 
     [2, 1, 8]]]) 
5

Использование scikit-изображения:

import numpy as np 
from skimage.util import view_as_blocks 

a = np.array([[1,5,9,13], 
       [2,6,10,14], 
       [3,7,11,15], 
       [4,8,12,16]]) 

print(view_as_blocks(a, (2, 2))) 
Смежные вопросы