Skyy2010
Skyy2010

Reputation: 855

numpy: pass by reference does not work on itself

I tried the following:

p=np.array([[1,1,1],[2,2,2],[3,3,3]])
p[0,:] = p[1,:]
y = p[1,:]
print(p)
p[1,1] = 4
print(p)
print(y)

As you can see the output is:

[[2 2 2]
 [2 2 2]
 [3 3 3]]
[[2 2 2]
 [2 4 2]
 [3 3 3]]
[2 4 2]

So when I assigned the second row of p to y it was passed by reference. When I assigned the second row of p to the first row of p it was passed by copy. Why is that the case?

The output I expected is:

[[2 2 2]
 [2 2 2]
 [3 3 3]]
[[2 4 2]
 [2 4 2]
 [3 3 3]]
[2 4 2]

Upvotes: 3

Views: 146

Answers (1)

MB-F
MB-F

Reputation: 23637

In short, the difference:

  • accessing a slice of an array (... = p[]) creates a new view into the data if possible.
  • assigning to a slice of an array (p[] = ...) copies elemets into the array.

The long story:

After p = np.array([[1,1,1],[2,2,2],[3,3,3]]) p holds the original data.

y = p[1,:] gives you a view into the data held by p (You can verify this by looking at y.base, which is p). This is not an assignment into an array, but y is a completely new object that shares data with p. Think of it like this:

Data: [1, 1, 1, 2, 2, 2, 3, 3, 3]
       ^        ^
       p        y

The data is just a block of memory. p points to the beginning of this memory and y points somewhere in the middle. (They don't merely "point" but also contain additional information about dimensions and who owns the data, but this is not important here.)

It is important to recognize that an array points only to the beginning of its associated data. Then it simply uses dimensions and step sizes (strides) to interpret the data as vectors, matrices, etc. Remember: one array - one pointer.

p[0,:] = p[1,:] here we assign a part of p to another part of the array. To get the expected behavior different parts of p would need to point to the same block of data. This is not possible (but something similar can be achieved in a limited way by cleverly manipulating strides). Instead, the data is copied.

Upvotes: 2

Related Questions