Hi!
I wrote a simple subclass of np.ndarray and now i do call np.sum() on it. I expected that the result will be a python float (or int) just like when summing up regular arrays. Instead i obtain the (scalar) view of my subclass. How can i change this behavior? I tried writing __array_wrap__ method like this:
def __array_wrap__(self, out_arr, context=None): selfv = self.view(np.ndarray) return np.ndarray.__array_wrap__(selfv, out_arr, context)
but this just returns np.ndarray type and not float.
Regards,
On Thu, Nov 20, 2014 at 5:47 PM, Marek Wojciechowski mwojc@p.lodz.pl wrote:
Hi!
I wrote a simple subclass of np.ndarray and now i do call np.sum() on it. I expected that the result will be a python float (or int) just like when summing up regular arrays. Instead i obtain the (scalar) view of my subclass. How can i change this behavior? I tried writing __array_wrap__ method like this:
def __array_wrap__(self, out_arr, context=None): selfv = self.view(np.ndarray) return np.ndarray.__array_wrap__(selfv, out_arr, context)
but this just returns np.ndarray type and not float.
There isn't really any reason to call __array_wrap__ here. Just compute whatever value you want and return it. If you want a float then return that :-). (Something like if selfv.ndim == 0: return selfv[()] )
As a bit of advice, if you can possibly avoid subclassing ndarray, then you probably should. There are a lot of painful little quirks that you'll run into.
-n
Dnia piÄ…tek, 21 listopada 2014 00:09:51 Nathaniel Smith pisze:
On Thu, Nov 20, 2014 at 5:47 PM, Marek Wojciechowski mwojc@p.lodz.pl
wrote:
Hi!
I wrote a simple subclass of np.ndarray and now i do call np.sum() on it. I expected that the result will be a python float (or int) just like when summing up regular arrays. Instead i obtain the (scalar) view of my subclass. How can i change this behavior? I tried writing __array_wrap__ method like this:> def __array_wrap__(self, out_arr, context=None): selfv = self.view(np.ndarray) return np.ndarray.__array_wrap__(selfv, out_arr, context)
but this just returns np.ndarray type and not float.
There isn't really any reason to call __array_wrap__ here. Just compute whatever value you want and return it. If you want a float then return that :-). (Something like if selfv.ndim == 0: return selfv[()] )
As a bit of advice, if you can possibly avoid subclassing ndarray, then you probably should. There are a lot of painful little quirks that you'll run into.
Thanks for the answer. I thought similar, but the 'context' argument confused me a bit. I do not know what for it is here.
Thanks also for the (reasonable) advice. Subclassing was just the fastest way to implement what i wanted to do, because of all these methods being on place. However i do see now, that that was not necessarily the best choice...
Dnia czwartek, 20 listopada 2014 18:47:41 Marek Wojciechowski pisze:
Hi!
I wrote a simple subclass of np.ndarray and now i do call np.sum() on it. I expected that the result will be a python float (or int) just like when summing up regular arrays. Instead i obtain the (scalar) view of my subclass. How can i change this behavior? I tried writing __array_wrap__ method like this:
def __array_wrap__(self, out_arr, context=None): selfv = self.view(np.ndarray) return np.ndarray.__array_wrap__(selfv, out_arr, context)
but this just returns np.ndarray type and not float.
Hi!
I'm back with the problem of returning types form ndarray subclasses, now with ravelling the array. I wrote the __array_wrap__ function like this:
def __array_wrap__(self, out_arr, context=None): arr = out_arr.view(np.ndarray) if arr.ndim == 0: arr = arr[()] return arr
I was convinced that now ufuncs wil return always numpy arrays. But now i discovered that for example:
a.ravel()
returns still the subclass type, not ndarray type. Ravel method apparently does not call __array_wrap__ (whereas np.ravel(a) does!). Is there a systematic way to resolve this or i need to write new ravel method?
Regards,