[Numpy-discussion] Ransom Proposals
Tim Hochberg
tim.hochberg at cox.net
Sat Mar 25 15:29:13 EST 2006
Sasha wrote:
>On 3/24/06, Tim Hochberg <tim.hochberg at cox.net> wrote:
>
>
[SNIP]
>
>
>>* reshape -- The origination of that whole, enormous thread was with
>>reshape and what its return behaviour should be. Currently it returns a
>>view if possible, otherwise it returns a copy. That's evil behaviour. I
>>believe that it should either always return a copy or return a view if
>>possible and otherwise raise an exception. I think I actually prefer the
>>later, although it's probably a more disruptive change, since its more
>>flexible when combined with asarray and friends. One possible
>>compromise would be to have numpy.reshape always copy, while
>>array.reshape always returns a view.
>>
>>
>>
>Could you, please provide some examples of the current behavior that
>you find undesired and how yuo would fix it? I believe the
>inconsistency is that x.reshape(shape) is x depends on shape. This is
>easy to fix. Do you also suggest that x.reshape(...).__array_data__
>is x.__array_data__ should be False?
>
>
Hmmm. I should defer discussion of x.reshape(shape) because I've never
used it . I only use the function reshape, not the method; I'm old
school ;) If this thread keeps dragging on I imagine I'll have to go
look into exactly what x.reshape does.
As for the function, the issue I have with it is that:
reshape(obj, shape)
may return a view or a copy of 'obj'. Which depends at least on what
'obj' is and may depend on shape as well. I admit I don't remember --
nor should I have to.
Here's a simple example. Suppose I have some image data that is stored
in a flat array [R, G, B, R, G, B, ....]. Now suppose I have a function
that converts this to grey scale in place by averaging the data
def suck_color_from(obj):
rbg = reshape(obj, [-1. 3])
grey = (rgb[:,0] + rgb[:,1] + rgb[:,2]) / 3.0
rgb[:,0] = rgb[:,1] = rgb[:,2] = grey
Now, this will work find as long as reshape is returning a view.
However, if reshape does not return a view, let's say obj is a list, it
will fail. And not *just* fail, it will fail silently. There are obvious
ways to fix this program (set obj.shape instead of using reshape, for
example), but the fewer perils I need to remember the better. That's why
I'd like to sweep all the view/shape indeterminacy into a few asXXXarray
functions. Everything else should always return a view or always return
a copy. Here's another example, in this case we are returning a new rgb
object:
def make_bland_picture_from(obj):
obj = copy(obj)
rbg = reshape(obj, [-1. 3])
grey = (rgb[:,0] + rgb[:,1] + rgb[:,2]) / 3.0
rgb[:,0] = rgb[:,1] = rgb[:,2] = grey
return obj
Again this works fine until someone passes in a list or other nonarray
sequence. Then, again, it fails silently. If reshape either always
returned a copy, or always returned a view, this kind of trap would not
be available.
I believe numpy.transpose also suffers from this behaviour.
My preferred behaviour is that reshape and transpose always returns a
view. That is, reshape(somelist) would become a type error. Always
returning a copy makes it a little more tedius to write some kinds of
code efficiently, however I still think it would be better than the
current situation. As for x.copy(), while I don't know what the current
situation is, I think it should always return a copy.
Regards,
Tim
More information about the NumPy-Discussion
mailing list