2013-06-01 4 views
8

Вопрос обратный this question. Я ищу для общего метода из исходного большого массива из небольших массивов:Форма большого массива 2d из нескольких меньших массивов 2d

array([[[ 0, 1, 2], 
     [ 6, 7, 8]],  
     [[ 3, 4, 5], 
     [ 9, 10, 11]], 
     [[12, 13, 14], 
     [18, 19, 20]],  
     [[15, 16, 17], 
     [21, 22, 23]]]) 

-> 

array([[ 0, 1, 2, 3, 4, 5], 
     [ 6, 7, 8, 9, 10, 11], 
     [12, 13, 14, 15, 16, 17], 
     [18, 19, 20, 21, 22, 23]]) 

Я в настоящее время разрабатывает решения, разместим его, когда это будет сделано, тем не менее хотелось бы, чтобы другие (лучше) способов.

ответ

18
import numpy as np 
def blockshaped(arr, nrows, ncols): 
    """ 
    Return an array of shape (n, nrows, ncols) where 
    n * nrows * ncols = arr.size 

    If arr is a 2D array, the returned array looks like n subblocks with 
    each subblock preserving the "physical" layout of arr. 
    """ 
    h, w = arr.shape 
    return (arr.reshape(h//nrows, nrows, -1, ncols) 
       .swapaxes(1,2) 
       .reshape(-1, nrows, ncols)) 


def unblockshaped(arr, h, w): 
    """ 
    Return an array of shape (h, w) where 
    h * w = arr.size 

    If arr is of shape (n, nrows, ncols), n sublocks of shape (nrows, ncols), 
    then the returned array preserves the "physical" layout of the sublocks. 
    """ 
    n, nrows, ncols = arr.shape 
    return (arr.reshape(h//nrows, -1, nrows, ncols) 
       .swapaxes(1,2) 
       .reshape(h, w)) 

Например,

c = np.arange(24).reshape((4,6)) 
print(c) 
# [[ 0 1 2 3 4 5] 
# [ 6 7 8 9 10 11] 
# [12 13 14 15 16 17] 
# [18 19 20 21 22 23]] 

print(blockshaped(c, 2, 3)) 
# [[[ 0 1 2] 
# [ 6 7 8]] 

# [[ 3 4 5] 
# [ 9 10 11]] 

# [[12 13 14] 
# [18 19 20]] 

# [[15 16 17] 
# [21 22 23]]] 

print(unblockshaped(blockshaped(c, 2, 3), 4, 6)) 
# [[ 0 1 2 3 4 5] 
# [ 6 7 8 9 10 11] 
# [12 13 14 15 16 17] 
# [18 19 20 21 22 23]] 

Обратите внимание, что есть также superbatfish's blockwise_view. Он устраивает блоки в другом формате (используя больше осей), но имеет то преимущество, что (1) всегда возвращает представление и (2) способен передавать массивы любого размера .

+0

Это не работает для 'c = np.arange (24) .reshape ((6,4))' 'print (unblockshaped (blockshaped (a, 3, 2), 6, 4))' – TheMeaningfulEngineer

+0

'blockshaped' как ожидается. Проблема в 'unblockshaped' – TheMeaningfulEngineer

+1

Да, у меня был порядок аргументов, чтобы« изменить форму »неправильно. Попробуй это сейчас. – unutbu

1

Я надеюсь, что я вам прямо, скажем, у нас есть a,b:

>>> a = np.array([[1,2] ,[3,4]]) 
>>> b = np.array([[5,6] ,[7,8]]) 
    >>> a 
    array([[1, 2], 
      [3, 4]]) 
    >>> b 
    array([[5, 6], 
      [7, 8]]) 

для того, чтобы сделать это один большой 2d массив использовать numpy.concatenate:

>>> c = np.concatenate((a,b), axis=1) 
>>> c 
array([[1, 2, 5, 6], 
     [3, 4, 7, 8]]) 
+0

Что я поиск метода ia, который может перестроить большой массив (изображение) из меньших массивов. Мне нужно, чтобы оно было общим, поэтому оно может применяться к изображениям разных размеров. Как нарезка в jpeg. Нарисуйте изображение до 8 × 8 блоков, выполните операции над каждым блоком, перестройте исходное изображение из блоков. – TheMeaningfulEngineer

0

Он работает для изображений, которые я тестировал. Будет, если будут проведены дальнейшие испытания. Это, однако, решение, которое не учитывает скорость и использование памяти.

def unblockshaped(blocks, h, w): 
    n, nrows, ncols = blocks.shape 
    bpc = w/ncols 
    bpr = h/nrows 

    reconstructed = zeros((h,w)) 
    t = 0 
    for i in arange(bpr): 
     for j in arange(bpc): 
      reconstructed[i*nrows:i*nrows+nrows,j*ncols:j*ncols+ncols] = blocks[t] 
      t = t+1 
    return reconstructed 
3

Еще один (простой) подход:

threedarray = ... 
twodarray = np.array(map(lambda x: x.flatten(), threedarray)) 
print(twodarray.shape) 
0

Вот решение, которое можно использовать, если кто-то желает создать плитки матрицы:

from itertools import product 
import numpy as np 
def tiles(arr, nrows, ncols): 
    """ 
    If arr is a 2D array, the returned list contains nrowsXncols numpy arrays 
    with each array preserving the "physical" layout of arr. 

    When the array shape (rows, cols) are not divisible by (nrows, ncols) then 
    some of the array dimensions can change according to numpy.array_split. 

    """ 
    rows, cols = arr.shape 
    col_arr = np.array_split(range(cols), ncols) 
    row_arr = np.array_split(range(rows), nrows) 
    return [arr[r[0]: r[-1]+1, c[0]: c[-1]+1] 
        for r, c in product(row_arr, col_arr)] 
Смежные вопросы