简体   繁体   English

为矩阵中的每个元素使用不同的填充填充 N 维矩阵 - Python

[英]Padding an N-dimension Matrix with different paddings for each element in the matrix - Python

I am trying to pad two dimensions of an N-dimensional matrix with different paddings and override the values.我正在尝试用不同的填充填充 N 维矩阵的两个维度并覆盖这些值。 Consider the Following example:考虑以下示例:

def determineShifts(layer):
    u = range(0, 2*layer + 1)
    b = range(0, 2*layer + 1)
    shifts = []
    mat = np.zeros((2 * layer + 1, 2 * layer + 1), dtype=object)
    for x, i in enumerate(u):
        for y, j in enumerate(b):
            up = (j, 2*layer - j)
            left = (i, 2*layer - i)
            mat[x, y] = (left, up)
    return mat

layer = 1

b = np.ones((3,3,3,3))
shifts = determineShifts(layer)

I want to pad the second last and final dimension of the array b such that the resulting shape is (3,3,5,5) and override the element of that matrix and repeat the process for all nodes, which in this case is (3,3).我想填充数组 b 的倒数第二个和最后一个维度,使得结果形状为 (3,3,5,5) 并覆盖该矩阵的元素并对所有节点重复该过程,在本例中为 ( 3,3)。 I would prefer to override the values (currently I receive a broadcasting error) rather than making a copy of the desired shape and iterating through the first and second dimension.我宁愿覆盖这些值(目前我收到一个广播错误),而不是制作所需形状的副本并遍历第一维和第二维。 A sample is included below:下面包含一个示例:

c = np.ones((3,3,5,5))
for i in range(np.shape(c)[0]):
    for j in range(np.shape(c)[1]):
        c[i,j] = np.pad(b[i,j], shifts[i,j])

Is there some way to apply a function to the matrix to apply all the shifts to each of the elements (3,3, 3, 3) -> (3, 3, 5, 5) such that the code is computationally efficient?是否有某种方法可以将 function 应用于矩阵以将所有移位应用于每个元素 (3,3,3,3) -> (3, 3, 5, 5) 以使代码具有计算效率?

np.pad() accepts different padding values for each axis, but not different ones within each axis, as per your example.根据您的示例, np.pad()接受每个轴的不同填充值,但每个轴没有不同的填充值。

One general approach is to do a bit of arithmetic for the relocation of elements and then use fancy indexing.一种通用方法是对元素的重定位进行一些算术运算,然后使用精美的索引。 In your case, it looks like you are trying to stagger the 2D blocks of the last two dimensions in such a way that they move by 1: vertically for axis 0 and horizontally for axis 1.在您的情况下,您似乎正试图错开最后两个维度的 2D 块,使它们移动 1:轴 0 垂直,轴 1 水平移动。

You can do the same with the following arithmetic:您可以使用以下算术执行相同操作:

def stagger_ix(s):
    r = np.arange(np.prod(s))
    block = r // np.prod(s[-2:])
    shift_i, shift_j = block // s[1], block % s[1]
    i, j = r // s[-1] % s[-2], r % s[-1]
    
    newshape = np.array(s)
    newshape[-2:] += newshape[:2] - 1
    
    ix = (
        block * np.prod(newshape[-2:])
        + (i + shift_i) * newshape[-1]
        + (j + shift_j)
    )
    return newshape, ix

def stagger(b):
    newshape, ix = stagger_ix(b.shape)

    # now insert b in a zero(newshape), as per shift logic
    c = np.zeros(np.prod(newshape), dtype=b.dtype)
    c[ix] = b.ravel()
    c = c.reshape(newshape)
    return c

Your c array can be obtained as:您的c数组可以通过以下方式获得:

c = stagger(np.ones((3,3,3,3)))

Other examples -其他例子——

# for example matrices
def rp1(s):
    return (np.arange(np.prod(s)) + 1).reshape(s)

>>> stagger(rp1((2,2,2,2)))
array([[[[ 1,  2,  0],
         [ 3,  4,  0],
         [ 0,  0,  0]],

        [[ 0,  5,  6],
         [ 0,  7,  8],
         [ 0,  0,  0]]],


       [[[ 0,  0,  0],
         [ 9, 10,  0],
         [11, 12,  0]],

        [[ 0,  0,  0],
         [ 0, 13, 14],
         [ 0, 15, 16]]]])
>>> stagger(rp1((2,3,2,5)))
array([[[[ 1,  2,  3,  4,  5,  0,  0],
         [ 6,  7,  8,  9, 10,  0,  0],
         [ 0,  0,  0,  0,  0,  0,  0]],

        [[ 0, 11, 12, 13, 14, 15,  0],
         [ 0, 16, 17, 18, 19, 20,  0],
         [ 0,  0,  0,  0,  0,  0,  0]],

        [[ 0,  0, 21, 22, 23, 24, 25],
         [ 0,  0, 26, 27, 28, 29, 30],
         [ 0,  0,  0,  0,  0,  0,  0]]],


       [[[ 0,  0,  0,  0,  0,  0,  0],
         [31, 32, 33, 34, 35,  0,  0],
         [36, 37, 38, 39, 40,  0,  0]],

        [[ 0,  0,  0,  0,  0,  0,  0],
         [ 0, 41, 42, 43, 44, 45,  0],
         [ 0, 46, 47, 48, 49, 50,  0]],

        [[ 0,  0,  0,  0,  0,  0,  0],
         [ 0,  0, 51, 52, 53, 54, 55],
         [ 0,  0, 56, 57, 58, 59, 60]]]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM