Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if __array_wrap__ on ndarray subclass is called from unary ufunc or binary ufunc

Tags:

python

numpy

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)

like image 950
mgilson Avatar asked Mar 08 '13 15:03

mgilson


People also ask

Can We subclass ndarray in NumPy?

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.

When to use asanyarray in ndarray?

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.

What happens when NumPy ufuncs execute on a subclass?

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.

What is userarray in NumPy?

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.


1 Answers

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.

like image 120
mgilson Avatar answered Oct 18 '22 18:10

mgilson