[Numpy-discussion] Ransom Proposals

Tim Hochberg tim.hochberg at cox.net
Mon Mar 27 09:13:06 CST 2006


Colin J. Williams wrote:

> Tim Hochberg wrote:
>
>> Bill Baxter wrote:
>>
>>>
>>>
>>> On 3/26/06, *Fernando Perez* <Fernando.Perez at colorado.edu 
>>> <mailto:Fernando.Perez at colorado.edu>> wrote:
>>>
>>>     > Or, you can use the reshape method instead of function.  I 
>>> believe
>>>     > numpy advocates use of methods instead of functions.  What you
>>>     observe
>>>     > is just another reason for that.  Since functions like reshape
>>>     remain
>>>     > in numpy primarily for backwards compatibility, I would be
>>>     against any
>>>     > change in semantics.
>>>
>>>     Mmh.  I bet many people will continue to use the functional
>>>     interface for a
>>>     long time.
>>>
>>>
>>> And maybe they'd be right to want a functional interface, too:  
>>> http://www.gotw.ca/gotw/084.htm
>>>
>>>
>>> The author argues that in general, you should make as few functions 
>>> as possible be members of a class, always preferring non-member 
>>> functions wherever possible.   It's about C++, but the principle 
>>> should apply to Python as well.  It does make a certain kind of 
>>> sense, although the article seems to completely ignore polymorphism, 
>>> which seems like it would be another good reason to have functions 
>>> be members, at least in C++.
>>
>>
>>
>>
>> Personally, I've always prefered the functional interface, but it 
>> appears that for historical / backwards compatibility reasons our 
>> choice is between a functional interface that is broken and a working 
>> method based interface. For that reason alone, I'm now in favor of 
>> ditching the functional interface to 'reshape' and 'transpose'.
>
>
> The transpose function handles a list and returns an array.  

Yes. And this is exactly the same property that I've been ranting about 
incessantly for the past several days in the case of reshape. It seems 
convenient, but it's evil. It leads to intermittent, hard to find bugs, 
since when passed a list it necessarily creates a new array object, but 
when passed an array, it returns a view.

> Of course the case could be made that things would be clearer if the 
> user wrote the longer:
> a= array([[1, 2]]).transpose()
> in place of:
> a=transpose([[1, 2]])

The best way to do deal with this is to make sure everything is an array 
at the boundaries of your function.

    def frobinate(a, b):
        a = asarray(a)
        b = asarray(b)
        bar = a.transpose()
        stool = a.reshape([1,2,3])
        # etc,
        c =
    asarray(get_data_from_somewhere_that_might_not_return_an_array())
        # etc.

It would easy enough to automate this using decorators if the extra 
lines bothers people. Thus the above could become:

    @array_arguments
    def frobinate(a, b):
        bar = a.transpose()
        stool = a.reshape([1,2,3])
        # etc,
        c =
    asarray(get_data_from_somewhere_that_might_not_return_an_array())
        # etc.

In either case, then you can use all of the array functions without 
worry, and with maximum efficiency, in the body of your function.

> Perhaps extension of the T property to the array would simplify things:
> a=array([[1, 2]]).T


I tend to think that the 'T' property should stay put. 'T' is really 
specific to two dimensional arrays and looses much of its appeal when 
applied to multidimensional arrays since it takes no arguments. I think 
it adds more clutter than functionality, so I'm -1 on that idea.

Regards,

-tim





More information about the Numpy-discussion mailing list