是否有避免这些循环的麻木魔法?

Is there a numpy magic avoiding these loops?

我想避免此代码段中的 for 循环:

import numpy as np

N = 4
a = np.random.randint(0, 256, size=(N, N, 3))
m = np.random.randint(0, 2, size=(N, N))

for i, d0 in enumerate(a):
  for j, d1 in enumerate(d0):
    if m[i, j]:
      d1[2] = 42

这是一个简化示例,其中 a 是 N x N RGB 图像,m 是 N x N 掩码,它设置了第 3 个通道的掩码元素:a[:, :, 2]只有.

以下对我有用。

a[:,:,2] *= (1-m)
a[:,:,2] += m*42

您可以索引最后一个轴并设置通过布尔掩码选择的元素

import numpy as np

N = 4
a = np.random.randint(0, 256, size=(N, N, 3))
m = np.random.randint(0, 2, size=(N, N))

a[...,2][m.astype('bool')] = 42
a

输出(对于 a 的随机示例)

array([[[ 9, 13,  4],
        [15,  0, 42],
        [11, 12,  9],
        [13,  0, 42]],

       [[ 1, 10, 42],
        [ 9,  0, 42],
        [ 8,  6,  4],
        [ 3,  0, 42]],

       [[15, 11,  6],
        [ 8, 11, 42],
        [14,  1, 42],
        [ 4, 14,  1]],

       [[ 3,  6, 42],
        [ 5, 13,  3],
        [ 9, 14, 13],
        [12,  6, 42]]])