numpy 索引:将矢量添加到部分行,从不同的位置开始
numpy indexing: add vector to parts of rows, starting at varying position
我有这个二维零数组 z
和这个一维起点数组 starts
。另外,我有一个 offsets
z = z = np.zeros(35, dtype='i').reshape(5, 7)
starts = np.array([1, 5, 3, 0, 3])
offsets = np.arange(5) + 1
我想在这里对这个小 for 循环进行矢量化,但我似乎做不到。
for i in range(z.shape[0]):
z[i, starts[i]:] += offsets[i]
此示例中的结果应如下所示:
z
array([[0, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 2, 2],
[0, 0, 0, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4, 4],
[0, 0, 0, 5, 5, 5, 5]])
我们可以使用一些 masking
and NumPy broadcasting
-
mask = starts[:,None] <= np.arange(z.shape[1])
z[mask] = np.repeat(offsets, mask.sum(1))
我们可以玩broadcasted multiplication
的把戏来得到最终的输出-
z = offsets[:,None] * mask
其他方法是将值从 offsets
分配到 z
,然后屏蔽掉 mask
的其余部分,就像这样 -
z[:] = offsets[:,None]
z[~mask] = 0
其他方法是从 offsets
复制一个版本作为起始 z
然后屏蔽掉 -
z = np.repeat(offsets,z.shape[1]).reshape(z.shape[0],-1)
z[~mask] = 0
当然,我们事先需要形状参数。
如果 z
没有初始化为 zeros
数组,那么只有前面提到的解决方案之一适用,并且需要用 +=
更新,就像这样 -
z[mask] += np.repeat(offsets, mask.sum(1))