Is there a way to tell if a ndarray subclass's __array_wrap__
is called with a unary function or a binary function? (another reference)
If we subclass ndarray, we need to deal not only with explicit construction of our array type, but also View casting or Creating new from template. NumPy has the machinery to do this, and it is this machinery that makes subclassing slightly non-standard.
If you are confident that your use of the array object can handle any subclass of an ndarray, then asanyarray can be used to allow subclasses to propagate more cleanly through your subroutine. In principal a subclass could redefine any aspect of the array and therefore, under strict guidelines, asanyarray would rarely be useful.
A subclass can override what happens when executing numpy ufuncs on it by overriding the default ndarray.__array_ufunc__ method. This method is executed instead of the ufunc and should return either the result of the operation, or NotImplemented if the operation requested is not implemented.
For backward compatibility and as a standard “container “class, the UserArray from Numeric has been brought over to NumPy and named numpy.lib.user_array.container The container class is a Python class whose self.array attribute is an ndarray.
This is only a partial answer:
The arguments to the ufunc are passed in as a tuple to context
. The form is:
(ufunc, ufunc_args, ufunc_domain)
You can check the length of ufunc_args
to see if you got 1 argument or 2. As a side note, I have no idea what ufunc_domain
is (in my tests, it always seems to be 0
)...
import numpy as np
class Tester(np.ndarray):
def __array_wrap__(self,output,context=None):
print context[0].__name__,'is binary' if len(context[1]) > 1 else 'is unary'
return np.ndarray.__array_wrap__(self,output,context)
a = np.zeros(10)
b = a.view(Tester)
print (type(b))
-b
np.sqrt(b)
b+b
I suppose this is how you can tell __array_wrap__
whether it is a binary or unary ufunc. Unfortunately, when I asked the question in the beginning, I was hoping to know if this ufunc call was the result of a unary operator. I didn't think of things like np.abs
and np.sqrt
as unary
functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With