如何在掩码指定的更大数组中的不同位置应用相同的一组值?

How can I apply the same set of values at various positions in a larger array, specified by masks?

我有一个二维数组 Y,维度 N x N,还有一个 K 二进制掩码数组 X,每个维度 M x M(所以, X 的形状为 K x M x M)。 X 中的每个二进制掩码只有一个 N x N 块,其余元素为零。我想创建一个 K x M x M 数组 Z,在 X 指定的位置包含 Y 的元素,其他地方为零。

例如,如果 M = 3N = 2K = 3

X = [[[1., 1., 0.],
     [1., 1., 0.],
     [0., 0., 0.]],

    [[0., 1., 1.],
     [0., 1., 1.],
     [0., 0., 0.]],

    [[0., 0., 0.],
     [0., 1., 1.],
     [0., 1., 1.]]]

Y = [[0.1, 0.2],
    [0.3, 0.4]]

那么Z应该是

Z = [[[0.1, 0.2, 0.],
     [0.3, 0.4, 0.],
     [0., 0., 0.]],

    [[0., 0.1, 0.2],
     [0., 0.3, 0.4],
     [0., 0., 0.]],

    [[0., 0., 0.],
     [0., 0.1, 0.2],
     [0., 0.3, 0.4]]]

我想使用 Numpy 或 Pytorch 中的函数来完成此操作。我认为使用 numpy.where() 或许可以做到这一点

Z = numpy.zeros((3,3,3))
Z[numpy.where(X == 1)] = Y

但这会导致形状不匹配错误。

最简洁有效的方法是什么(除了显式使用循环来设置值)?

寻址数值示例,可以使用:

Z[X==1] = np.tile(Y.reshape(-1,),3)
Z

array([[[0.1, 0.2, 0. ],
       [0.3, 0.4, 0. ],
        [0. , 0. , 0. ]],

       [[0. , 0.1, 0.2],
        [0. , 0.3, 0.4],
        [0. , 0. , 0. ]],

       [[0. , 0. , 0. ],
        [0. , 0.1, 0.2],
        [0. , 0.3, 0.4]]])

一般情况只需要用K代替np.tile中的3即可。

试试这个:

X[X == 1] = np.tile(Y.flatten(), X.shape[0])

您可以将掩码更改为索引,然后重塑以利用广播:

idx = *np.reshape(X.nonzero(),(3,3,2,2)),
Z = np.zeros_like(X)
Z[idx] = Y
Z
array([[[0.1, 0.2, 0. ],
        [0.3, 0.4, 0. ],
        [0. , 0. , 0. ]],

       [[0. , 0.1, 0.2],
        [0. , 0.3, 0.4],
        [0. , 0. , 0. ]],

       [[0. , 0. , 0. ],
        [0. , 0.1, 0.2],
        [0. , 0.3, 0.4]]])

或使用平面索引相同:

idx = X.ravel().nonzero()[0].reshape(3,4)
Z = np.zeros_like(X)
Z.ravel()[idx] = Y.ravel()