从多个较小的2d阵列形成一个大的2d阵列

时间:2013-06-01 13:54:29

标签: python numpy

问题是this question的倒数。我正在寻找一个通用的方法来从小数组的原始大数组:

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

我目前正在开发一种解决方案,会在完成后发布,但是希望看到其他(更好)的方式。

5 个答案:

答案 0 :(得分:26)

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)能够处理任何数组 尺寸。

答案 1 :(得分:3)

又一种(简单)方法:

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

答案 2 :(得分: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]])

答案 3 :(得分: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

答案 4 :(得分: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)]