[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