Reputation: 314
Say I have the numpy
array arr_1 = np.arange(10)
returning:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
How do I change multiple elements to a certain value using slicing?
For example: changing the zeroth, first and second element that occur every five elements, starting from the first element, to 100. I want this:
array([0, 100, 100, 100, 4, 5, 100, 100, 100, 9])
I tried arr_1[1::[5, 6, 7]] = 100
but that doesn't work.
Upvotes: 3
Views: 1559
Reputation: 53029
If your repeat offset divides the array length:
a.reshape((-1, 5))[:, 1:4] = 100
General case requires two lines:
a[: len(a) // 5 * 5].reshape((-1, 5))[:, 1:4] = 100
a[len(a) // 5 * 5 :][1:4] = 100
How it works: Reshaping in the described way stacks consecutive stretches of the array in such a way that the target substretches are aligned and can therefore be addressed in one go using standard 2d indexing:
>>> a = np.arange(15)
>>> a.reshape((-1, 5))
array([[ 0, 1x, 2x, 3x, 4],
[ 5, 6x, 7x, 8x, 9],
[10, 11x, 12x, 13x, 14]])
Upvotes: 1
Reputation: 1564
You just need to wrap your list of indexes in np.array(list). You were very close to being correct:
In [2]: arr_1 = np.arange(10)
In [3]: arr_1[np.array([0,1,2,5,6,7])] = 100
In [4]: arr_1
Out[4]: array([100, 100, 100, 3, 4, 100, 100, 100, 8, 9])
I used hand coded values for the indexes, per your requirements. You can get the indexes in an automated way using some technique you like, like that shown by Divakar.
Upvotes: 0
Reputation: 221564
Here's one approach with masking
-
a = np.arange(10) # Input array
idx = np.array([0,1,2]) # Indices to be set
offset = 1 # Offset
a[np.in1d(np.mod(np.arange(a.size),5) , idx+offset)] = 100
Sample run with original sample -
In [849]: a = np.arange(10) # Input array
...: idx = np.array([0,1,2]) # Indices to be set
...: offset = 1 # Offset
...:
...: a[np.in1d(np.mod(np.arange(a.size),5) , idx+offset)] = 100
...:
In [850]: a
Out[850]: array([ 0, 100, 100, 100, 4, 5, 100, 100, 100, 9])
Sample run with non-sequential indices
-
In [851]: a = np.arange(11) # Input array
...: idx = np.array([0,2,3]) # Indices to be set
...: offset = 1 # Offset
...:
In [852]: a[np.in1d(np.mod(np.arange(a.size),5) , idx+offset)] = 100
In [853]: a
Out[853]: array([ 0, 100, 2, 100, 100, 5, 100, 7, 100, 100, 10])
Upvotes: 0
Reputation: 989
Here is another solution based on what you did :
arr_1 = np.arange(10)
arr_1[1::5] = 100
arr_1[2::5] = 100
arr_1[3::5] = 100
and it returns :
array([ 0, 100, 100, 100, 4, 5, 100, 100, 100, 9])
Upvotes: 1