14

这个问题是这个问题的反面。我正在寻找一种从小数组中提取原始大数组的通用方法:

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

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

4

5 回答 5

36
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 的 blockwise_view. 它以不同的格式排列块(使用更多轴),但它具有以下优点:(1)始终返回视图和(2)能够处理任何维度的数组。

于 2013-06-01T14:32:46.807 回答
4

另一种(简单)方法:

threedarray = ...
twodarray = np.array(map(lambda x: x.flatten(), threedarray))
print(twodarray.shape)
于 2016-06-27T00:04:51.023 回答
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]])

为了使它成为一个大的二维数组,请使用numpy.concatenate

>>> c = np.concatenate((a,b), axis=1 )
>>> c
array([[1, 2, 5, 6],
       [3, 4, 7, 8]])
于 2013-06-01T14:15:59.253 回答
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
于 2013-06-02T09:54:52.663 回答
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)]
于 2016-06-28T10:37:31.487 回答