[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