【问题标题】:Form a big 2d array from multiple smaller 2d arrays由多个较小的二维数组组成一个大的二维数组
【发布时间】:2013-05-28 05:29:17
【问题描述】:

问题是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]])

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

【问题讨论】:

    标签: python numpy


    【解决方案1】:
    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)能够处理任何数组 维度。

    【讨论】:

    • 不适用于c = np.arange(24).reshape((6,4)) print(unblockshaped(blockshaped(a, 3, 2), 6, 4))
    • blockshaped 按预期返回。问题出在unblockshaped
    • 是的,我对reshape 的参数顺序错误。立即尝试。
    • 主要问题是n * nrows * ncols = arr.size 不成立。比如size=17或size=47这样的素数,就不能用这个方法。
    • @SudiptaBasak:这不是问题,因为没有二维数组arr,arr.size 等于素数。
    【解决方案2】:

    另一种(简单)方法:

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

    【讨论】:

    • 感谢您的简洁。 +1
    【解决方案3】:

    我希望我说对了,假设我们有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]])
    

    【讨论】:

    • 我正在寻找一种可以从较小的数组重建大数组(图像)的方法。我需要它是通用的,以便它可以应用于不同尺寸的图像。就像在 jpeg 中切片一样。将图像切片为 8×8 块,对每个块进行操作,从块中重建原始图像。
    【解决方案4】:

    它适用于我现在测试的图像。如果做进一步的测试会。然而,这是一个不考虑速度和内存使用的解决方案。

    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
    

    【讨论】:

      【解决方案5】:

      如果有人希望创建矩阵图块,可以使用以下解决方案:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-12
        • 2023-03-04
        • 1970-01-01
        • 2021-10-29
        • 2021-06-03
        • 2013-05-19
        相关资源
        最近更新 更多