0

I have an vector, x (a numpy array), and I want to create two copies of this; one (y) where the even points are set to zero and one, z, where the odd points are set to zero. I have come up with two possible ways of doing this.

1)

x = numpy.array([1,2,3,4,5,6,7,8,9,10])
y = x
y[::2] = 0

Result

x
array([ 0,  2,  0,  4,  0,  6,  0,  8,  0, 10])

y
array([ 0,  2,  0,  4,  0,  6,  0,  8,  0, 10])

z = x
z[:,1::2] = 0

Result:

x
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
z
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

Or:

2)

y = numpy.zeros(10)
y[::2] = x[::2]

Result:

y
array([ 1.,  0.,  3.,  0.,  5.,  0.,  7.,  0.,  9.,  0.])
x
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

z = numpy.zeros(10)
z[1::2] = x[1::2]

Result:

z
array([  0.,   2.,   0.,   4.,   0.,   6.,   0.,   8.,   0.,  10.])
x
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

The first method seems to have x coupled to y and z so that any changes to y or z affect x too. The second seems a less-intuitive way of writing this but gives the intended results. Why do these two methods give different results? The first in particular seems rather dangerous in terms of keeping track of what is happening in your code!

218
  • 1,754
  • 7
  • 27
  • 38

2 Answers2

2

When you assign x to y you are not copying the array you are merely pointing the variable to the object x.

if you check in your code the following should evaluate to true.

x is y

You can also have a look at the unique id of the object. It should match.

id(x) == id(y)

You can use the copy function in numpy to avoid these issue.

numpy copy documentation

Todd
  • 61
  • 3
1

In Python, y = x just makes y point to the same object as x. So changes to y will also affect x. y[::2] = 0 changes y,x.

z = numpy.zeros(10)

z is a brand new object, without any connection to x.

z[1::2] = x[1::2]

copies values from x to z, changing z, but doing nothing to x.

z = x.copy() would also make an independent copy of xs data.

What I've written so far applies to other Python objects like lists and dictionaries. But np.arrays have a further complication, the distinction between views and copies.

z = x[1::2] is a view. Futher changes to z will affect x. z=x[[1,3,5,7,9]] is a copy. Changes to z will not affect x.

This is a fundamental part of numpy, especially indexing, so I'd encourage you to study the documentation in more detail.

hpaulj
  • 221,503
  • 14
  • 230
  • 353