简体   繁体   中英

Changing multiple Numpy array elements using slicing in Python

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.

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

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM