I think this is what you want to do - but with the loop:
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]])
Since there differing length slices, this will be tricky to do with one array expression. Maybe not impossible, but tricky enough that it might not be worth trying.
Look at the indices of the 1s in this z
:
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))
Is there a regular pattern that could be generated [0,1,2,3] and index
?
I can generate the 2nd row with a concatenation of slices:
In [39]: np.r_[1:2, 2:4, 1:5, 5:6]
Out[39]: array([1, 2, 3, 1, 2, 3, 4, 5])
But notice that r_
involves several iterations - to generate the input, to generate the expanded slices, and to concatenate them.
I can generate the first row of the where
with:
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])
and as expected, those 2 index arrays give us all the 1s:
In [43]: z[Out[42],Out[39]]
Out[43]: array([1, 1, 1, 1, 1, 1, 1, 1])
Or to generate Out[39]
from index
:
In [50]: np.concatenate([np.arange(i,j) for i,j in index])
Out[50]: array([1, 2, 3, 1, 2, 3, 4, 5])
Comparing my solutions with @Divakar's
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
For this small example, row iteration is faster:
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)
Even for larger arrays, the row iteration approach is faster:
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
after the desired change. – July