A derived class from a numpy array does not work very well with a matrix and masked array

I am trying to subclass numpy ndarray, but I cannot get permission to operate on other numpy types, such as a masked array or matrix. It seems to me that __ array_priority __ is not respected. As an example, I created a dummy class that mimics important aspects:

import numpy as np class C(np.ndarray): __array_priority__ = 15.0 def __mul__(self, other): print("__mul__") return 42 def __rmul__(self, other): print("__rmul__") return 42 

The operations between my class and normal ndarray work as expected:

 >>> c1 = C((3, 3)) >>> o1 = np.ones((3, 3)) >>> print(o1 * c1) __mul__ 42 >>> print(c1 * o1) __rmul__ 42 

But, when I try to work with a matrix (or masked arrays), the priority of the array is not respected.

 >>> m = np.matrix((3, 3)) >>> print(c1 * m) __mul__ 42 >>> print(m * c1) Traceback (most recent call last): ... File "/usr/lib64/python2.7/site-packages/numpy/matrixlib/defmatrix.py", line 330, in __mul__ return N.dot(self, asmatrix(other)) ValueError: objects are not aligned 

It seems to me that the ufuncs method is wrapped in a matrix, and masked arrays do not respect the priority of the array. This is true? Is there a workaround?

+6
source share
1 answer

The workaround is to subclass np.matrixib.defmatrix.matrix :

 class C(np.matrixlib.defmatrix.matrix): __array_priority__ = 15.0 def __mul__(self, other): print("__mul__") return 42 def __rmul__(self, other): print("__rmul__") return 4 

In this case, priority is also higher than np.ndarray , and your multiplication methods are always called.

As added in the comments, you can subclass from several classes if you need interoperability:

 class C(np.matrixlib.defmatrix.matrix, np.ndarray): 
+2
source

Source: https://habr.com/ru/post/950676/


All Articles