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

Christopher Barker Chris.Barker at noaa.gov
Thu Feb 1 12:38:12 EST 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)

I'm not sure what this means exactly.

> 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.

yes, weird. So why not just:

a = numpy.flipud(a)

Since flipud returns a view, the new "a" will still be using the same 
data array. Does this satisfy your need above?

You've created a new numpy array object, but that was created by flipud 
anyway, so there is no performance loss.

It's too bad that to do this you need to know that flipud created a 
view, rather than a copy of the data, as if it were a copy, you would 
need to do the a[:] trick to make sure a kept the same data, but that's 
the price we pay for the flexibility and power of numpy -- the 
alternative is to have EVERYTHING create a copy, but there were be a 
substantial performance hit for that.

NOTE: the docstring doesn't make it clear that a view is created:

 >>> help(numpy.flipud)
Help on function flipud in module numpy.lib.twodim_base:

flipud(m)
     returns an array with the columns preserved and rows flipped in
     the up/down direction.  Works on the first dimension of m.

NOTE2: Maybe these kinds of functions should have an optional flag that 
specified whether you want a view or a copy -- I'd have expected a copy 
in this case!

QUESTION:
How do you tell if two arrays are views on the same data: is checking if 
they have the same .base reliable?

 >>> a = numpy.array((1,2,3,4))
 >>> b = a.view()
 >>> a.base is b.base
False

No, I guess not. Maybe .base should return self if it's the originator 
of the data.

Is there a reliable way? I usually just test by changing a value in one 
to see if it changes in the other, but that's one heck of kludge!

 >>> a.__array_interface__['data'][0] == b.__array_interface__['data'][0]
True

seems to work, but that's pretty ugly!

-Chris

-- 
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov



More information about the NumPy-Discussion mailing list