我认为这是您想要做的事情 - 但使用循环实现:
In [35]: z=np.zeros((4,10),int)
In [36]: index = np.array([[1,2],[2,4],[1,5],[5,6]])
In [37]: for i in range(4):
...: z[i,index[i,0]:index[i,1]] = 1
...:
In [38]: z
Out[38]:
array([[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]])
由于切片长度不同,使用单个数组表达式可能会很棘手。也许不是不可能,但足够棘手,可能不值得尝试。
看一下这个z
中1的索引:
In [40]: np.where(z)
Out[40]:
(array([0, 1, 1, 2, 2, 2, 2, 3], dtype=int32),
array([1, 2, 3, 1, 2, 3, 4, 5], dtype=int32))
有没有一种规律可以生成 [0,1,2,3] 和 index
?
我可以通过切片的拼接生成第二行:
In [39]: np.r_[1:2, 2:4, 1:5, 5:6]
Out[39]: array([1, 2, 3, 1, 2, 3, 4, 5])
但请注意,
r_
包含多个迭代步骤 - 用于生成输入、生成扩展切片并将它们连接起来。
我可以使用以下代码生成
where
的第一行:
In [41]: index[:,1]-index[:,0]
Out[41]: array([1, 2, 4, 1])
In [42]: np.arange(4).repeat(_)
Out[42]: array([0, 1, 1, 2, 2, 2, 2, 3])
正如预期的那样,这两个索引数组给出了所有的1:
In [43]: z[Out[42],Out[39]]
Out[43]: array([1, 1, 1, 1, 1, 1, 1, 1])
或者从 index
生成 Out[39]
:
In [50]: np.concatenate([np.arange(i,j) for i,j in index])
Out[50]: array([1, 2, 3, 1, 2, 3, 4, 5])
将我的解决方案与 @Divakar 的进行比较。
def foo0(z,index):
for i in range(z.shape[0]):
z[i,index[i,0]:index[i,1]] = 1
return z
def foo4(z,index):
r = np.arange(z.shape[1])
mask = (index[:,0,None] <= r) & (index[:,1,None] >= r)
z[mask] = 1
return z
对于这个小例子,行迭代更快:
In [155]: timeit foo0(z,index)
7.12 µs ± 224 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [156]: timeit foo4(z,index)
19.8 µs ± 890 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
即使对于较大的数组,行迭代方法也更快:
In [157]: Z.shape
Out[157]: (1000, 1000)
In [158]: Index.shape
Out[158]: (1000, 2)
In [159]: timeit foo0(Z,Index)
1.72 ms ± 16.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [160]: timeit foo4(Z,Index)
7.47 ms ± 105 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
z
。 - hpaulj