I am trying to subclass my own subclass of numpy.ndarray. I really donโt understand what the problem is, and I would like someone to explain what is wrong in the following cases, and how to do what I am trying to do.
What I'm trying to achieve:
I have a subclass of numpy.ndarry that behaves the way I want (class A in the code below). I want to subclass A (class B in the code below), so B contains additional information (name) and methods (decorated method .simple_data).
Case 1:
import numpy as np class A(np.ndarray): def __new__(cls,data): obj = np.asarray(data).view(cls) return obj def __array_finalize(self,obj): if obj is None: return class B(A): def __init__(self,data,name): super(B,self).__init__(data) self.name = name @property def simple_data(self): return [data[0,:],data[:,0]] if __name__ == '__main__': data = np.arange(20).reshape((4,5)) b = B(data,'B') print type(b) print b.simple_data
Running this code outputs the result:
Traceback (most recent call last): File "ndsubclass.py", line 24, in <module> b = B(data,'B') TypeError: __new__() takes exactly 2 arguments (3 given)
I assume that this is due to the variable "name" in construct B and that because A is a subclass of numpy.array, A new method is called before B init . Thus, to fix this, I assume that B also needs a new method that handles the additional argument accordingly.
My guess is like:
def __new__(cls,data,name): obj = A(data) obj.name = name return obj
should do this, but how to change the obj class?
Case 2:
import numpy as np class A(np.ndarray): def __new__(cls,data): obj = np.asarray(data).view(cls) return obj def __array_finalize__(self,obj): if obj is None: return class B(A): def __new__(cls,data): obj = A(data) obj.view(cls) return obj def __array_finalize__(self,obj): if obj is None: return @property def simple_data(self): return [self[0,:],self[:,0]] if __name__ == '__main__': data = np.arange(20).reshape((4,5)) b = B(data) print type(b) print b.simple_data()
At startup, the output:
<class '__main__.A'> Traceback (most recent call last): File "ndsubclass.py", line 30, in <module> print b.simple_data() AttributeError: 'A' object has no attribute 'simple_data'
This surprises me as I expected:
<class '__main__.B'> [array([0, 1, 2, 3, 4]), array([ 0, 5, 10, 15])]
I assume that calling view () in B. new () incorrectly defines the obj class. Why?
I am confused about what is happening and would be very grateful if anyone could explain this.