[Numpy-discussion] Ransom Proposals
Travis Oliphant
oliphant.travis at ieee.org
Tue Mar 28 12:41:03 CST 2006
Tim Hochberg wrote:
>
> +1 Assuming I understand all of the implications.
>
> * When doing automated conversion from Numeric/numarray to numpy,
> "reshape(obj) => asarray(obj).reshape()". Doing anything else is going
> to cause breakage and/or massive slowdowns. Can the conversion tool
> handle this? I would guess yes, but that's just a guess.
Why would we need to change this --- even to
ascontiguousarray(obj).reshape()?
>
> * This means that "somenoncontiguousarray.reshape(newshape)" will
> oftern raise an error. That's a good thing, but I figured I'd get it
> out in the open now so no one is suprised.
I'm still not sold that raising an error here is a good thing, which is
why I think the function should work as it always as and *not* be
deprecated or hard to get at even if the method is changed to raise an
error if the reshape cannot be accomplished without a copy.
Discontiguous arrays actually show up quite a bit. I'm not convinced
that Tim's concern over "confusion" between when something returns a
view and when it returns a copy is that big of a deal. I maintain it's
only disconcerting for someone who wants to do something "advanced".
That person will know how to figure it out. If things are "fixed" then
new users will get bitten by slow code or errors that don't make sense.
I'm opposed to making things unnecessarily hard for new users.
Let's discuss this with a particular example in mind that is not
contrived to do 'in-place' operations. I think this will exemplify the
crux of the matter for those who may not quite understand what this
discussion is about.
a = rand(4,5,3)
b = a.transpose().reshape(15,4)
c = a.reshape(15,4)
In this example b is now a copy of the data in a and c is a "view" of
the data in a. The reason for this is because a.transpose() returns a
"view" of the data which is not C-style contiguous. The reshape
function needs to know how to go between a linear sequence of elements
and a multidimensional array --- the default is current C-style
contiguous (last-index varies the fastest).
If I understand correctly, Tim want's the second line to raise an error
so that the reshape method *always* returns a view. I'm not enthused
about having the second line raise an error because it is an example of
common code (perhaps a transpose does not precede the reshape but a
slice selection --- there are lots of ways to get discontiguous
arrays). As it stands, I think the only problems that arise are when
the user wants to modify b and/or c in-place. Then, one is not sure
whether or not b (or c) is pointing to the data of a or not.
My argument is that the reshape method documentation should state that
you should not modify the contents of the return value of reshape unless
it doesn't matter whether or not you have a copy of the data. I would
even be willing to make 'views' un-writeable by default so that there
was no way to "inadvertently" modify the data in a, unless you know you
want to.
We had this discussion for ravel months ago and the flatten method which
always returns copies was created. The ravel method is another one
that returns views when it can (contiguous) and copies when it can't.
I think reshape and ravel are the only methods that behave this way.
I'm not convinced that changing their current, standard behavior is
going to buy us anything but more confusion.
>
> * Since x.reshape would no longer return copies, the order flag is
> unnecessary.
I don't believe this. See my other posts on the difference between the
array striding and how you want to interpret the array.
>
> * numpy.reshape(obj, newshape) on the other hand, always copies, so it
> *could* grow an order flag. I think that I'd prefer that it didn't; if
> you need that kind of control of the resulting arrays you should be
> using array to copy your matrices.
No, this is not what I understand. the reshape function would not
*always* copy but would behave as it currently does. Again, you haven't
sold me on the need to absolutely, all the time, return either views or
copies. I think such a dogmatic view is too limiting in this case.
I have not been bitten by this in over 10 years. Why is this such an
issue now?
>
> * What does fixing ravel to be consistent mean? Always return a view?
> Or always return a copy? The latter seems more useful, as the first is
> already covered by both obj.reshape(-1) and obj.flat.
I meant that whatever the behavior is for .reshape should be the same
for .ravel since it is syntactic sugar for obj.reshape(-1)
And obj.flat is not even in the same ball-park since it returns an
array_iterator object and not an array.
Best,
-Travis
More information about the Numpy-discussion
mailing list