0

I was trying to do a shallow copy of numpy arrays using [:], like i normally would do with lists. However i found that this does not behave same as lists. I know that i can use .copy() method to solve this. But just wanted to understand whats happening under the hood with numpy here. can anyone please elaborate.

import numpy as np
a = np.array([1,2,3,4,5])
b = a[:]
print(id(b) == id(a))  # Ids are different, So different objects right ?
b[3] = 10
print(a, b) # Both a and b got updated
Ak4704
  • 11
  • 2
  • i think it's a different pointer, but it points to the same place in memory. sort of like int* a, b; int c; a = &c; b = a – yann ziselman Oct 11 '21 at 10:36
  • 2
    The operator [:] for numpy arrays creates a view (that is why the objects are different), but do not copies the internal data, if you need a copy do .copy – Dani Mesejo Oct 11 '21 at 10:37
  • agree with @DaniMesejo. you can verify this by using b.base which gives you a. read this for better understanding: https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference –  Oct 11 '21 at 10:40

2 Answers2

2

From the documentation on slicing (emphasis mine):

Note that slices of arrays do not copy the internal array data but only produce new views of the original data. This is different from list or tuple slicing and an explicit copy() is recommended if the original data is not required anymore.

So just do:

import numpy as np

a = np.array([1, 2, 3, 4, 5])
b = a.copy()
b[3] = 10
print(a, b)

Output

[1 2 3 4 5] [ 1  2  3 10  5]

Notice that the reason the ids are different is because b is a view of a and indeed a different object.

Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
0

The operator [:] in numpy does not copy the data, but the reference. So that kind of behavior is expected. It's same as you do the a = b directly. Use the np.copy(array) to copy the values.

If there's array a = [1, 2], and the empty variable b, so the behavior of assignments of numpy array are summarized into this:

  1. These kind of assignments will copy the reference, so if you change the b later, it will also change a.
b = a
b[1] = 10
print(b == a) # True
b = a[:]
b[1] = 10
print(b == a) # True
  1. This kind of assignment will copy the values, so if you change b later, a won't change.
b = np.copy(a)
b[1] = 10
print(b == a) # True

...and if the dtype=object, the use of deepcopy() from package copy will make sure all the values copied.

b = copy.deepcopy(a)
b[1] = 10
print(b == a) # True
Dhana D.
  • 1,670
  • 3
  • 9
  • 33