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

use*_*857 2 numpy vectorization

我有一个二维数组:

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]]
Run Code Online (Sandbox Code Playgroud)

目标是,对于每一行,r用 0 替换r+1该行的每个第(从第 0 个)元素。即,对于第 0 行,用 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]]
Run Code Online (Sandbox Code Playgroud)

我可以在这里利用 numpy 的矢量化功能并避免循环吗?还是不可能?

Mic*_*sny 5

您可以使用 anp.arangemodulo对其自身进行广播

import numpy as np

H = 12

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

输出

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]])
Run Code Online (Sandbox Code Playgroud)