用对角带的numpy操作替换循环

时间:2019-03-19 12:06:21

标签: numpy

是否可以在没有显式循环的情况下生成以下数组?

nrows, ncols = 5, 3 
d = np.zeros((nrows, nrows * ncols), dtype=np.uint8)
for i in range(nrows):
    d[i][i * ncols:(i + 1) * ncols] = 1
print(d)
[[1 1 1 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 1 1 1 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 1 1 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 1 1]]

3 个答案:

答案 0 :(得分:3)

使用np.eye + np.repeat

np.repeat(np.eye(nrows), ncols, axis=1)

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

答案 1 :(得分:1)

您可以使用np.einsum

nrows, ncols = 5, 3
out = np.zeros((nrows, nrows*ncols), 'u1')
np.einsum('iik->ik', out.reshape(nrows, nrows, ncols))[...] = 1
out
# array([[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]], dtype=uint8)

答案 2 :(得分:0)

怎么样:

import numpy as np
ix = np.indices((5,15))
d = (ix[1] //3  == ix[0]).astype(int)
d
>> array([[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]])