将二维数组切片成较小的二维数组

有没有办法将nd数组中的2d数组切分成更小的2d数组?

[[1,2,3,4],   ->    [[1,2] [3,4]   
 [5,6,7,8]]          [5,6] [7,8]]

所以我基本上想要将2x4阵列分割成2个2x2阵列。 寻找在图像上使用的通用解决方案。



在我看来,这是numpy.split或其他变体的一项任务。

例如

a = np.arange(30).reshape([5,6])  #a.shape = (5,6)
a1 = np.split(a,3,axis=1) 
#'a1' is a list of 3 arrays of shape (5,2)
a2 = np.split(a, [2,4])
#'a2' is a list of three arrays of shape (2,5), (2,5), (1,5)

如果您有可以创建的NxN图像,例如,2 NxN / 2个子图像的列表,然后将它们沿着另一个轴划分。

numpy.hsplitnumpy.vsplit也可用。


还有一些其他答案似乎已经非常适合您的特定情况,但您的问题激起了我对可以使用高达numpy支持的最大维数的内存高效解决方案的兴趣,并且我最终花费了大部分下午提出可能的方法。 (该方法本身相对简单,只是我还没有使用numpy支持的大多数真正奇特的功能,因此大部分时间都花在研究上以查看numpy可用的数量以及它可以做多少,以使我没有不必这样做。)

def blockgen(array, bpa):
    """Creates a generator that yields multidimensional blocks from the given
array(_like); bpa is an array_like consisting of the number of blocks per axis
(minimum of 1, must be a divisor of the corresponding axis size of array). As
the blocks are selected using normal numpy slicing, they will be views rather
than copies; this is good for very large multidimensional arrays that are being
blocked, and for very large blocks, but it also means that the result must be
copied if it is to be modified (unless modifying the original data as well is
intended)."""
    bpa = np.asarray(bpa) # in case bpa wasn't already an ndarray

    # parameter checking
    if array.ndim != bpa.size:         # bpa doesn't match array dimensionality
        raise ValueError("Size of bpa must be equal to the array dimensionality.")
    if (bpa.dtype != np.int            # bpa must be all integers
        or (bpa < 1).any()             # all values in bpa must be >= 1
        or (array.shape % bpa).any()): # % != 0 means not evenly divisible
        raise ValueError("bpa ({0}) must consist of nonzero positive integers "
                         "that evenly divide the corresponding array axis "
                         "size".format(bpa))


    # generate block edge indices
    rgen = (np.r_[:array.shape[i]+1:array.shape[i]//blk_n]
            for i, blk_n in enumerate(bpa))

    # build slice sequences for each axis (unfortunately broadcasting
    # can't be used to make the items easy to operate over
    c = [[np.s_[i:j] for i, j in zip(r[:-1], r[1:])] for r in rgen]

    # Now to get the blocks; this is slightly less efficient than it could be
    # because numpy doesn't like jagged arrays and I didn't feel like writing
    # a ufunc for it.
    for idxs in np.ndindex(*bpa):
        blockbounds = tuple(c[j][idxs[j]] for j in range(bpa.size))

        yield array[blockbounds]
链接地址: http://www.djcxy.com/p/68109.html

上一篇: Slice 2d array into smaller 2d arrays

下一篇: Broadcasting a 1d numpy array with a 2d numpy array