[Numpy-discussion] array copy-to-self and views

Travis Oliphant oliphant@ee.byu....
Thu Feb 1 13:30:33 CST 2007

Zachary Pincus wrote:

>Hello folks,
>I recently was trying to write code to modify an array in-place (so  
>as not to invalidate any references to that array) via the standard  
>python idiom for lists, e.g.:
>a[:] = numpy.flipud(a)
>Now, flipud returns a view on 'a', so assigning that to 'a[:]'  
>provides pretty strange results as the buffer that is being read (the  
>view) is simultaneously modified. Here is an example:

This is a known feature of the "view" concept.   It has been present in 
Numeric from the beginning. Performing operations in-place using a view 
always gives "hard-to-predict" results.  It depends completely on how 
the algorithms are implemented.  

Knowing that numpy.flipud(a)  is just a different way to write 
a[::-1,...]  which works for any nested-sequence, helps you realize that 
if a is already an array, then it returns a reversed view, but when 
copied back into itself creates the results you obtained but might not 
have bee expecting.
You can understand the essence of what is happening with a simpler example:

a = arange(10)
a[:] = a[::-1]

What is a?

It is easy to see the answer when you realize that the code is doing the 
equivalent of

a[0] = a[9]
a[1] = a[8] 
a[2] = a[7] 
a[3] = a[6] 
a[4] = a[5]
a[5] = a[4]
a[6] = a[3]
a[7] = a[2]
a[8] = a[1]
a[9] = a[0]

Notice that the final 5 lines are completely redundant, so really all 
that is happening is

a[:5] = a[5:][::-1]

There was an explicit warning of the oddities of this construct in the 
original Numeric documentation.

Better documentation of the flipud function to indicate that it returns 
a view is definitely desireable.  In fact, all functions that return 
views should be clear about this in the docstring.

In addition, all users of "in-place" functionality of NumPy must be 
aware of the view concept and realize that you could be modifying the 
array you are using.

This came up before when somebody asked how to perform a "diff" in place 
and I was careful to make sure and not change the input array before it 
was used.

>A question, then: Does this represent a bug? Or perhaps there is a  
>better idiom for modifying an array in-place than 'a[:] = ...'? Or is  
>incumbent on the user to ensure that any time an array is directly  
>modified, that the modifying array is not a view of the original array?
Yes, it is and has always been incumbent on the user to ensure that any 
time an array is directly modified in-place that the modifying array is 
not a "view" of the original array.

Good example...


More information about the Numpy-discussion mailing list