Blockwise operations in Numpy

前端 未结 3 1037
难免孤独
难免孤独 2021-01-04 13:08

Are there any convenience utilities for doing blockwise operations on Numpy arrays?

I am thinking of operations like Ising spin renormalization where you divide a ma

3条回答
  •  悲哀的现实
    2021-01-04 14:05

    This can also be done with simple reshaping. The idea is to interleave the number of blocks and the block size for each dimension.

    For example, with an array of shape (6, 12, 20), and targeting a block size of (2, 3, 4), reshaping to (3, 2, 4, 3, 5, 4) will do.

    After the reshaping, the block position and the block size axes are alternating:

    • even indexes refer to the block repetitions
    • odd indexes refer to the block sizes

    but they can easily be rearranged with np.transpose().

    A 2D example follows:

    import numpy as np
    
    block_shape = 2, 2
    repeats = 3, 3
    
    m = repeats[0] * block_shape[0]
    n = repeats[1] * block_shape[1]
    
    arr = np.arange((m * n)).reshape((m, n))
    print(arr)
    # [[ 0  1  2  3  4  5]
    #  [ 6  7  8  9 10 11]
    #  [12 13 14 15 16 17]
    #  [18 19 20 21 22 23]
    #  [24 25 26 27 28 29]
    #  [30 31 32 33 34 35]]
    
    block_shape = tuple(x for nm in zip(repeats, block_shape) for x in nm)
    # (3, 2, 3, 2)
    repeat_indexes = tuple(range(0, len(block_shape), 2))
    # 0, 2
    block_indexes = tuple(range(1, len(block_shape), 2))
    # 1, 3
    block_arr = arr.reshape(block_shape).transpose(repeat_indexes + block_indexes)
    print(block_arr)
    # [[[[ 0  1]
    #    [ 6  7]]
    #   [[ 2  3]
    #    [ 8  9]]
    #   [[ 4  5]
    #    [10 11]]]
    #  [[[12 13]
    #    [18 19]]
    #   [[14 15]
    #    [20 21]]
    #   [[16 17]
    #    [22 23]]]
    #  [[[24 25]
    #    [30 31]]
    #   [[26 27]
    #    [32 33]]
    #   [[28 29]
    #    [34 35]]]]
    

提交回复
热议问题