Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In numpy, q1 = p[:] instead of q1 = p, yet p is modified when I modify q1? [duplicate]

Tags:

python

numpy

I am getting baffled by how copying a Numpy array works in Python. I start with the following:

import numpy as np
p = np.array([1.0, 0.0, 1.0, 0.3])

Then I try to make "copies" of p using the following three methods:

q = p
q1 = p[:]
q2 = p.copy()

Now I execute q1[2] = 0.2, and then check the values of q, q1, and q2. I was surprised to find that p, q, and q1 all changed to array([1.0, 0.0, 0.2, 0.3]), while only q2 remains invariant. I have also used id() to check the address of all four variables (p, q, q1, q2), and have confirmed that id(p) = id(q), but id(q1) != id(p).

My question is, if id(q1) != id(p), how can a modification of q1 alters p and q? Thanks!

like image 933
Xiao Avatar asked Mar 26 '20 13:03

Xiao


2 Answers

The documentation of Numpy states:

All arrays generated by basic slicing are always views of the original array.

Therefore q1 in your case is a view of p and reflects the changes made to p.

like image 119
Jacques Gaudin Avatar answered Sep 28 '22 03:09

Jacques Gaudin


Because you are using a simple slicing operation, numpy will use a shared memory view of the resulting slice of the array. In this case it is the entire array. They are referenced by different python objects, but the underlying numpy array is the same. q1 is just a view into the same array that p is referencing.

You can check this using np.shared_memory.

import numpy as np
p = np.array([1.0, 0.0, 1.0, 0.3])

q1 = p[:]

np.shares_memory(p, q1)
# returns:
True

This is even true when the slice is not of the entire array. Such as:

p = np.array([1.0, 0.0, 1.0, 0.3])

q2 = p[1::2]
print(q2)
#prints:
[0.  0.3]

# setting a value of q2 changes p
q2[0] = 10.0
p
# returns:
array([ 1. , 10. ,  1. ,  0.3])
like image 40
James Avatar answered Sep 28 '22 03:09

James