[Numpy-discussion] Help on subclassing numpy.ma: __array_wrap__

Pierre GM pgmdevlist@gmail....
Tue Mar 3 12:57:43 CST 2009

Sorry for the delayed answer.
> (a) Is MA intended to be subclassed?

Yes, that's actually the reason why the class was rewritten, to  
simplify subclassing. As Josef suggested, you can check the  
scikits.timeseries package that makes an extensive use of MaskedArray  
as baseclass.

> (b) If so, perhaps I'm missing something to make this work.  Any  
> pointers will be appreciated.

As you've run a debugger on your sources, you must have noticed the  
calls to MaskedArray._update_from. In your case, the simplest is to  
define DTMA._update_from as such:
     def _update_from(self, obj):
         ma.MaskedArray._update_from(self, obj)
         self._attr = getattr(obj, '_attr', {'EmptyDict':[]})

Now, because MaskedArray.__array_wrap__() itself calls _update_from,  
you don't actually need a specific DTMA.__array_wrap__ (unless you  
have some specific operations to perform, but it doesn't seem to be  
the case).

Now for a word of explanation:
__array_wrap__ is intended to transform the output of a numpy function  
to an object of your class. When we use the numpy.ma functions, we  
don't need that, we just need to retrieve some of the attributes of  
the initial MA. That's why _update_from was introduced.
Of course, I'm to blame not to have make that aspect explicit in the  
doc. I gonna try to correct that.
In any case, let me know how it goes.

On Mar 1, 2009, at 10:37 AM, Kevin Dunn wrote:

> Hi everyone,
> I'm subclassing Numpy's MaskedArray to create a data class that  
> handles missing data, but adds some extra info I need to carrry  
> around. However I've been having problems keeping this extra info  
> attached to the subclass instances after performing operations on  
> them.
> The bare-bones script that I've copied here shows the basic issue: http://pastebin.com/f69b979b8 
>   There are 2 classes: one where I am able to subclass numpy (with  
> help from the great description at http://www.scipy.org/Subclasses),  
> and the other where I subclass numpy.ma, using the same ideas again.
> When stepping through the code in a debugger, lines 76 to 96, I can  
> see that the numpy subclass, called DT, calls DT.__array_wrap__()  
> after it completes unary and binary operations. But the numpy.ma  
> subclass, called DTMA, does not seem to call DTMA.__array_wrap__(),  
> especially line 111.
> Just to test this idea, I overrode the __mul__ function in my DTMA  
> subclass to call DTMA.__array_wrap__() and it returns my extra  
> attributes, in the same way that Numpy did.
> My questions are:
> (b) If so, perhaps I'm missing something to make this work.  Any  
> pointers will be appreciated.
> So far it seems the only way for me to sub-class numpy.ma is to  
> override all numpy.ma functions of interest for my class and add a  
> DTMA.__array_wrap() call to the end of them.  Hopefully there is an  
> easier way.
> Related to this question, was there are particular outcome from this  
> archived discussion (I only joined the list recently): http://article.gmane.org/gmane.comp.python.numeric.general/24315 
>   because that dictionary object would be exactly what I'm after here.
> Thanks,
> Kevin
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion@scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion

More information about the Numpy-discussion mailing list