1

I am new to numpy.Recently only I started learning.I am doing one practice problem and getting error. Question is to replace all even elements in the array by -1.

import numpy as np
np.random.seed(123)
array6 = np.random.randint(1,50,20)
slicing_array6 = array6[array6 %2==0]
print(slicing_array6)
slicing_array6[:]= -1
print(slicing_array6)
print("Answer is:")
print(array6)

I am getting output as :

[46 18 20 34 48 10 48 26 20]
[-1 -1 -1 -1 -1 -1 -1 -1 -1]
Answer is:
[46  3 29 35 39 18 20 43 23 34 33 48 10 33 47 33 48 26 20 15]

My doubt is why original array not replaced? Thank you in advance for help

2
  • From a guess, maybe the data is coppied on line 4. Commented Jun 12, 2022 at 15:20
  • But ideally slicing array should reflect in main array..correct? Commented Jun 12, 2022 at 15:39

3 Answers 3

2
In [12]: np.random.seed(123)
    ...: array6 = np.random.randint(1,50,20)
    ...: slicing_array6 = array6[array6 %2==0]

In [13]: array6.shape
Out[13]: (20,)

In [14]: slicing_array6.shape
Out[14]: (9,)

slicing_array6 is not a view; it's a copy. It does not use or reference the array6 data:

In [15]: slicing_array6.base

Modifying this copy does not change array6:

In [16]: slicing_array6[:] = -1

In [17]: slicing_array6
Out[17]: array([-1, -1, -1, -1, -1, -1, -1, -1, -1])

In [18]: array6
Out[18]: 
array([46,  3, 29, 35, 39, 18, 20, 43, 23, 34, 33, 48, 10, 33, 47, 33, 48,
       26, 20, 15])

But if the indexing and modification occurs in the same step:

In [19]: array6[array6 %2==0] = -1

In [20]: array6
Out[20]: 
array([-1,  3, 29, 35, 39, -1, -1, 43, 23, -1, 33, -1, -1, 33, 47, 33, -1,
       -1, -1, 15])

slicing_array6 = array6[array6 %2==0] has actually done

 array6.__getitem__(array6%2==0)

array6[array6 %2==0] = -1 does

 array6.__setitem__(array6 %2==0, -1)

A __setitem__ applied to a view does change the original, the base.

An example with view that works:

In [32]: arr = np.arange(10)    
In [33]: arr
Out[33]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [34]: x =  arr[::3]  # basic indexing, with a slice
In [35]: x
Out[35]: array([0, 3, 6, 9])
In [36]: x.base          # it's a `view` of arr
Out[36]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [37]: x[:] = -1
In [38]: arr
Out[38]: array([-1,  1,  2, -1,  4,  5, -1,  7,  8, -1])
Sign up to request clarification or add additional context in comments.

Comments

0

Explanation

Let's move step by step. We start with

array6 = np.array([46,  3, 29, 35, 39, 18, 20, 43, 23, 34, 33, 48, 10, 33, 47, 33, 48, 26, 20, 15])
print(array6 %2==0)

# array([ True, False, False, False, False,  True,  True, False, False,
#         True, False,  True,  True, False, False, False,  True,  True,
#         True, False])

You just made a mask (%2==0) to array6. Then you apply the mask to it and assign to a new variable:

slicing_array6 = array6[array6 %2==0]
print(slicing_array6)

# [46 18 20 34 48 10 48 26 20]

Note that this returns a new array:

print(id(array6))
# 2643833531968

print(id(slicing_array6))
# 2643833588112

print(array6)
# [46  3 29 35 39 18 20 43 23 34 33 48 10 33 47 33 48 26 20 15]
# unchanged !!

Final step, you assign all elements in slicing_array6 to -1:

slicing_array6[:]= -1
print(slicing_array6)
# [-1 -1 -1 -1 -1 -1 -1 -1 -1]

Solution

Instead of assigning masked array to a new variable, you apply new value directly to the original array:

array6[array6 %2==0] = -1
print(array6)
print(id(array6))

# [-1  3 29 35 39 -1 -1 43 23 -1 33 -1 -1 33 47 33 -1 -1 -1 15]
# 2643833531968
# same id !!

Comments

0

Numpy's slicing functionality directly modifies the array, but you have to assign the value you want to it. Not to completely ruin your learning, here is a similar example to what you are trying to achieve:

import numpy as np
a = np.arange(10)**3
print(f"start:  {a}")
#start:  [  0   1   8  27  64 125 216 343 512 729]

# to assign every 3rd item as -99
a[2::3] = -99

print(f"answer: {a}")
#answer: [  0   1 -99  27  64 -99 216 343 -99 729]

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.