[SciPy-User] subclassing ndarray : i want slice to return ndarray, not subclass

pierre puiseux pierre at puiseux.name
Mon May 21 09:57:05 EDT 2012


First, my problem is : 
Imagine ArrayChild is a subclass of np.ndarray and 'ac' is an instance of ArrayChild.
I call very often ac[i] or ac[1:12], which calls methods ArrayChild.__getislice__() or ArrayChild.__getiitem__() 
But for each call Python/NumPy create a new instance of ArrayChild, and calls my (very expansive) ArrayChild.__array_finalize__

I'd like to avoid this creation, and I want a more direct access to ArrayChild's slice or item

Finally, i've found a solution (I'm not sure it's less expansive, anyway) : 

first, i create a ndarray view of my ArrayChild in __array_finalize__.
where i add this line : 
======================================
self.array_view = obj.view(np.ndarray)
======================================

Then i define methods ArrayChild.__getslice__ and ArrayChild.__getitem__ to call the getters of array_view instead of default getters :

======================================
    def __getslice__(self, *args, **kwargs):
        return np.ndarray.__getslice__(self.array_view, *args, **kwargs)
                                       ---------------
    def __getitem__(self, *args, **kwargs):
        return np.ndarray.__getitem__(self.array_view, *args, **kwargs)
                                      ---------------
======================================
That's it, i have my results : subarray of ArrayChild are now np.ndarray s.
======================================
__array_finalize__
[0 1 2] <type 'numpy.ndarray'>
[3 4 5] <type 'numpy.ndarray'>
======================================

The final test program is :

======================================
import numpy as np

class ArrayChild(np.ndarray):

    def __new__(cls, array, info=None):
        obj = np.asarray(array).view(cls)
        obj.info = info
        return obj

    def __array_finalize__(self, obj):
        print>>sys.stderr, "__array_finalize__"
        if obj is None: return
        self.info = getattr(obj, 'info', None)
        self.array_view = obj.view(np.ndarray)
    
    def __getslice__(self, *args, **kwargs):
        return np.ndarray.__getslice__(self.array_view, *args, **kwargs)

    def __getitem__(self, *args, **kwargs):
        return np.ndarray.__getitem__(self.array_view, *args, **kwargs)

if __name__=='__main__':
    a = np.arange(6)
    a.shape=2,3
    a_child = ArrayChild(a)
    for x in a_child : 
        print>>sys.stderr, x, type(x)
======================================


Le 21 mai 2012 à 11:56, pierre puiseux UPPA a écrit :

> Hello,
> all my question is in the title. More precisely, like in scipy doc i try this :
> ======================================
> import sys
> import numpy as np
> 
> class ArrayChild(np.ndarray):
> 
>     def __new__(cls, array, info=None):
>         obj = np.asarray(array).view(cls)
>         obj.info = info
>         return obj
> 
>     def __array_finalize__(self, obj):
>         print>>sys.stderr, "__array_finalize__"
>         if obj is None: return
>         self.info = getattr(obj, 'info', None)
> 
> if __name__=='__main__':
>     a = np.arange(6)
>     a.shape=2,3
>     a_child = ArrayChild(a)
>     for x in a_child : 
>         print>>sys.stderr, x, type(x)
> 
> =====================================
> and i have the answer :
> =====================================
> __array_finalize__
> __array_finalize__
> [0 1 2] <class '__main__.ArrayChild'>
> __array_finalize__
> [3 4 5] <class '__main__.ArrayChild'>
> 
> =====================================
> but i want
> =====================================
> __array_finalize__
> __array_finalize__
> [0 1 2] <class '__main__.np.ndarray'>
> __array_finalize__
> [3 4 5] <class '__main__.np.ndarray'>
> 
> =====================================
> I've tried to redefine : __getslice__  like this, but it does not work.
> =====================================
>     def __getslice__(self, *args, **kwargs):
>         return np.ndarray.__getslice__(self, *args, **kwargs)
> 
> 
> =====================================
> Some idea ?
> Thanks to numpy/scipy team for that great job.
> =====================================
> 
> Pierre Puiseux
> Laboratoire de Mathématiques Appliquées
> Université de Pau et des Pays de l'Adour
> pierre.puiseux at univ-pau.fr
> http://www.univ-pau.fr/~puiseux
> 

pierre puiseux
pierre at puiseux.name
http://puiseux.name





-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.scipy.org/pipermail/scipy-user/attachments/20120521/e68beecf/attachment.html>


More information about the SciPy-User mailing list