Numpy Anamoly

Travis Oliphant olipt at mayo.edu
Tue Aug 22 11:23:28 EDT 2000


> 
> #############################################
> #test array lookup
> 
> from Numeric import *
> 
> class Tester:
>     def DoIt(self):
>         return 'DoIt'
> 
> a = array(((Tester(),)*3,)*3)
> print a[1,1].DoIt()    #here is the bad?? call

The problem is that right now a[1,1] returns a rank-0 array (unless the
element is a Python Float, Int, or Complex number).  I know this is kind
of messy, but it's there to prevent automatic upcasting --- Python doesn't
have single precision scalars....

To tell you the truth the Object case should probably have been included
in that list and so you've identified a "bug.", we can change that so that
your code will work. Did you compile your own copy?  If so just change the
following line in the function 
extern PyObject *PyArray_Return(PyArrayObject *mp) :


if (mp->nd == 0 && (mp->descr->type_num == PyArray_LONG ||
mp->descr->type_num == PyArray_DOUBLE || mp->descr->type_num ==
PyArray_CDOUBLE) ) {


change to

if (mp->nd == 0 && (mp->descr->type_num == PyArray_LONG ||
mp->descr->type_num == PyArray_DOUBLE || mp->descr->type_num ==
PyArray_CDOUBLE || mp->descr->type_num == PyArray_OBJECT) ) {


For now, or if you don't want to make the change you can also use the
toscalar() method which will return the actual object wrapped in the
rank-0 array.

a[1,1].toscalar().DoIt()    # this will break if and when the code change
                            #  happens unless your class has a toscalar
                            #  method of it's own.


Sorry for the confusion.


-Travis










More information about the Python-list mailing list