1

I have a class that is a subclass of numpy.ndarray. Following this example I have a class Test that behaves like numpy.ndarray but has an additional attribute description:

>>> f = Test([0., 1., 2.], description="f")
>>> f
array([0., 1., 2.])
>>> f.description
'f'

f behaves just like numpy.ndarray and the results of all mathematical operations will also have the description attribute.

>>> fplusone = f + 1.
>>> fplusone
array([1., 2., 3.])
>>> fplusone.description
'f'

In a more complex case it has the following behavior:

>>> g = Test([1., 3., 2], description="g")
>>> g
array([1., 3., 2.])
>>> g.description
'g'

>>> fplusg = f + g
>>> fplusg
array([1., 4., 4.])
>>> fplusg.description
'f'

>>> gplusf= g + f
>>> gplusf
array([1., 4., 4.])
>>> gplusf.description
'g'

Note: The order matters for the outcome of the description attribute.

That's a behavior I do not want. Basically I would like to have that the result of any math operation is a numpy.ndarray and not an instance of Test.

One idea is to overload all operators, e.g.:

>>> class Test2(Test):
>>>
>>>    def __add__(self, val):
>>>        return numpy.array(super().__add__(val))


>>> f2 = Test2([0., 1., 2.], description="f2")
>>> f2.description
'f2'
>>> (f2 + 1.).description
AttributeError: 'numpy.ndarray' object has no attribute 'description'

I would like to have this behavior for all Numpy ufuncs, too, e.g. this should also raise an AttributeError:

>>> fgmax = numpy.maximum(f, g)
>>> fgmax
array([1., 3., 2.])
>>> fgmax.description
'f'

So my questions are:
Is there an easy way of doing this without overloading every single arithmetic operator by hand? And how can this be achieved for every possible Numpy universal function?

I'm also having an eye on the overhead that is caused by invoking the additional numpy.array(). Something like this would invoke numpy.array() four times if implemented for all operators as shown above:

>>> f * g + f**2 / g

But all that matters for me is that the end result is a numpy.ndarray, e.g.:

>>> numpy.array(f * g + f**2 / g)
Sebastian
  • 755
  • 3
  • 7
  • 22
  • `MaskedArray` is a builtin example of a subclass that adds an attribute (the boolean mask). It overloads most methods and functions. – hpaulj Sep 03 '20 at 14:44

0 Answers0