6

我正在尝试子类化numpyndarray类,并且有一些运气。我想要的行为与文档中给出的示例几乎完全相同。我想向name数组添加一个参数(我用它来跟踪数据最初来自哪里)。

class Template(np.ndarray):
    """A subclass of numpy's n dimensional array that allows for a
    reference back to the name of the template it came from.
    """
    def __new__(cls, input_array, name=None):
        obj = np.asarray(input_array).view(cls)
        obj.name = name
        return obj

    def __array_finalize__(self, obj):
        if obj is None: return
        self.name = getattr(obj, 'name', None)

这可行,除了像这个问题一样,我希望涉及我的子类的任何转换都返回我的子类的另一个实例

有时 numpy 函数会返回一个实例Template

>>> a = Template(np.array([[1,2,3], [2,4,6]], name='from here')
>>> np.dot(a, np.array([[1,0,0],[0,1,0],[0,0,1]]))
Template([[1, 2, 3],
       [2, 4, 6]])

但是,有时他们不会:

>>> np.dot(np.array([[1,0],[0,1]]), a)
array([[1, 2, 3],
       [2, 4, 6]])

在我上面链接的问题中,建议 OP 应该覆盖__wrap_array__子类的方法。但是,我认为这没有任何理由。在某些情况下,我会使用默认的__array_wrap__. 文档似乎表明我遇到了一种情况,__array_wrap__即由于更高的__array_priority__值而调用了另一个参数的方法:

注意ufunc( np.add)调用了输入值__array_wrap__最高的方法__array_priority__

所以我的问题有几个相关的部分。第一:我可以设置__array_priority__我的子类的属性,使其__array_wrap__始终被调用吗?第二:这是实现我想要的行为的最好/最简单的方法吗?

4

1 回答 1

0

当两个对象具有相同的 __array_priority__ 时:

>>> np.array([[1,0],[0,1]]).__array_priority__
0.0
>>> a.__array_priority__
0.0

并且只能使用一个对象的方法,通过使用第一个数组/对象的方法来解决平局。(在你的情况下__array_wrap__)

从这个问题看来,您的类的方法似乎应该始终是首选,因为它们是相同的(通过继承)或被覆盖。

所以我会启动 __array_priority__。

class Template(np.ndarray):
    __array_priority__ = 1.0 (Or whichever value is high enough)
    ...

执行此操作后,无论模板对象在计算中的什么位置。它的方法将优于标准数组的方法。

于 2014-06-05T11:17:59.380 回答