3

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.

2
  • YOu are close -- just wrap your list of indexes in a numpy array constructor. See below for details. Commented Feb 7, 2017 at 15:53
  • Yes, slice arguments have to be numbers, not lists. Commented Feb 7, 2017 at 18:12

4 Answers 4

1

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])
Sign up to request clarification or add additional context in comments.

1 Comment

Or in loop form for i in range(3): arr_1[i::5] = 100. If the number of loops is sufficiently smaller than the length of arr_1 this should be faster than the 'fancier' solutions.
1

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]])

Comments

0

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])

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.