【问题标题】:Derived class from numpy array does not play well with matrix and masked arraynumpy 数组的派生类不能很好地与矩阵和掩码数组一起使用
【发布时间】:2013-07-31 08:59:18
【问题描述】:

我正在尝试对 numpy ndarray 进行子类化,但我无法正确使用其他 numpy 类型(例如掩码数组或矩阵)进行操作。在我看来, __array_priority__ 没有受到尊重。例如,我创建了一个模拟重要方面的虚拟类:

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

我的班级和 normal ndarray 之间的操作按预期工作:

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

但是,当我尝试使用矩阵(或掩码数组)进行操作时,不尊重数组优先级。

>>> 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

在我看来,为矩阵和掩码数组包装 ufunc 的方式不尊重数组优先级。是这样吗?有解决办法吗?

【问题讨论】:

  • 其实报错是因为他们没有对齐,因为np.matrix((3, 3))np.asmatrix(np.ones((3, 3)))不一样。但是,问题仍然存在,只是 m * c1 不起作用。
  • @GustavLarsson 感谢您发现这一点。我修复了它并在动机中添加了更多信息。

标签: python arrays numpy matrix subclassing


【解决方案1】:

一种解决方法是继承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

在这种情况下,优先级也高于np.ndarray,并且始终调用您的乘法方法。

正如在 cmets 中添加的那样,如果您需要互操作性,您可以从多个类中进行子类化:

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

【讨论】:

  • 这很好用,但是 ndarray 比矩阵更好地描述了我的类。此外,我的课程应该与 ndarray、matrix 和 masked darray 互操作。有没有办法做到这一点?
  • 尝试使用这种方法,看看是否实现互操作,如果没有,您可以从多个类中继承,例如:class C(np.matrixlib.defmatrix.matrix, np.ndarray):,例如...
  • 我已将类重新定义为class C(np.matrixlib.defmatrix.matrix, np.ma.core.MaskedArray, np.ndarray):。它很难看,但似乎有效,我仍然需要更多测试用例。我现在正在尝试对包装数组(没有子类化)的类做同样的事情。同样,它在乘以 ndarray 时工作正常,但不适用于其他任何事情。
  • 我认为您的情况的解决方案是在仅从 np.matrixlib.defmatrix.matrix 子类化不起作用时进行多重子类化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 2018-03-28
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多