'Set multiple rows slices to value, with a unique slice for each row
Given a 2d array, I can set a row slice to a particular value
import numpy as np
a = np.zeros(25).reshape(5,-1).astype(int)
a[0][2:4] = 1.0
a
array([[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
I am trying to set multiple row slices to a particular value, with a unique slice for each row.
I have the start and end indices for the slices in two arrays
starts = np.array([2, 0, 1, 3, 2])
ends = np.array([5, 3, 4, 5, 4])
But I can't seem to figure out a way to set these slices for the 2d array to a particular value
a[starts:ends] = 1
Results in TypeError: only integer scalar arrays can be converted to a scalar index
Solution 1:[1]
Numpy has a function that allows you apply operations to arrays, along a particular axis individually, using a function. So in my case, I can apply the operation uniquely to each row.
apply_along_axis doesn't allow arguments to be passed to the function except for the array itself, so I first concatenate the start and end indices to my zeros array, and then slice them out of the result.
import numpy as np
a = np.zeros(25).reshape(5,-1).astype(int)
starts = np.array([2, 0, 1, 3, 2])
ends = np.array([5, 3, 4, 5, 4])
startsT = np.expand_dims(starts, axis=0).transpose()
endsT = np.expand_dims(ends, axis=0).transpose()
aa = np.concatenate((a, startsT, endsT), axis=1)
def set_1s_by_slice(x):
x[x[-2]:x[-1]] = 1
return x
pen = np.apply_along_axis(set_1s_by_slice, 1, aa)
ult = pen[:,0:5]
ult
array([[0, 0, 1, 1, 1],
[1, 1, 1, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 1, 1],
[0, 0, 1, 1, 0]])
From looking at the source code, this may not be faster that iterating through the rows
https://github.com/numpy/numpy/blob/v1.22.0/numpy/lib/shape_base.py#L267-L414
It seems that there are conversions to lists, though I am not certain.
Solution 2:[2]
This seems even more computationally efficient than the other answer which uses apply_along_axis
indices = np.arange(a.shape[1])
mask = (indices >= starts[:, np.newaxis]) & (indices < ends[:, np.newaxis])
a[mask] = 1
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | SantoshGupta7 |
| Solution 2 | SantoshGupta7 |
