根据行号更改 2d numpy 数组中一行的每个第 n 个元素

Change every n-th element of a row in a 2d numpy array depending on the row number

我有一个二维数组:

H = 12
a = np.ones([H, H])
print(a.astype(int))

[[1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1 1 1]]

目标是,对于每一行 r,将该行的第 r+1 个(从第 0 个开始)元素替换为 0。 即,对于第 0 行,将每个 'first'(即所有这些)元素替换为 0。对于第一行,将每个第二个元素替换为 0。依此类推。

它可以简单地在一个循环中完成(打印的数组是期望的输出):

for i in np.arange(H):
    a[i, ::i+1] = 0

print(a.astype(int))

[[0 0 0 0 0 0 0 0 0 0 0 0]
 [0 1 0 1 0 1 0 1 0 1 0 1]
 [0 1 1 0 1 1 0 1 1 0 1 1]
 [0 1 1 1 0 1 1 1 0 1 1 1]
 [0 1 1 1 1 0 1 1 1 1 0 1]
 [0 1 1 1 1 1 0 1 1 1 1 1]
 [0 1 1 1 1 1 1 0 1 1 1 1]
 [0 1 1 1 1 1 1 1 0 1 1 1]
 [0 1 1 1 1 1 1 1 1 0 1 1]
 [0 1 1 1 1 1 1 1 1 1 0 1]
 [0 1 1 1 1 1 1 1 1 1 1 0]
 [0 1 1 1 1 1 1 1 1 1 1 1]]

我可以在这里利用 numpy 的矢量化能力并避免循环吗?或者不可能?

您可以使用 np.arange 并在其自身上广播 modulo

import numpy as np

H = 12

a = np.arange(H)
((a % (a+1)[:, None]) != 0).astype('int')

输出

array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
       [0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1],
       [0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1],
       [0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1],
       [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])