子类化ndarray

介绍

子类化ndarray相对简单,但与其他Python对象相比,它有一些复杂性。在这个页面上,我们解释了允许你子类化ndarray的机制,以及实现子类的含义。

#ndarrays和对象创建

ndarray的子​类化很复杂,因为ndarray类的新实例可以以三种不同的方式出现。这些是:

  1. 显式构造函数调用 - 如 MySubClass(params)。这是Python实例创建的常用途径。
  2. 查看转换 - 将现有的ndarray转换为给定的子类
  3. 模板中的新内容 - 从模板实例创建新实例。示例包括从子类化数组返回切片,从ufuncs创建返回类型以及复制数组。有关更多详细信息,请参阅
    从模板创建

最后两个是ndarrays的特性 - 为了支持数组切片之类的东西。子类化ndarray的复杂性是由于numpy必须支持后两种实例创建路径的机制。

视图投影

视图投影 是标准的ndarray机制,通过它您可以获取任何子类的ndarray,并将该数组的视图作为另一个(指定的)子类返回:

>>> import numpy as np>>> # create a completely useless ndarray subclass>>> class C(np.ndarray): pass>>> # create a standard ndarray>>> arr = np.zeros((3,))>>> # take a view of it, as our useless subclass>>> c_arr = arr.view(C)>>> type(c_arr)

从模板创建

当numpy发现它需要从模板实例创建新实例时,ndarray子类的新实例也可以通过与视图投影非常相似的机制来实现。
这个情况的最明显的时候是你正为子类数组切片的时候。例如:

>>> v = c_arr[1:]>>> type(v) # the view is of type 'C'>>> v is c_arr # but it's a new instanceFalse

切片是原始 c_arr 数据的 视图 。因此,当我们从ndarray中获取视图时,我们返回一个同一类的新ndarray,它指向原始数据。

在使用ndarrays时还有其它要点,我们需要这样的视图,例如复制数组(c_arr.copy()),创建ufunc输出数组(参见__array_wrap__用于ufuncs和其他函数),
以及减少方法(如c_arr.mean()。

视图投影与从模板创建的关系

这些路径都使用相同的机器。我们在这里进行区分,因为它们会为您的方法带来不同的输入。具体来说,
视图投影意味着您已从ndarray的任何潜在子类创建了数组类型的新实例。
从模板创建意味着您已从预先存在的实例创建了类的新实例,例如,允许您跨特定于您的子类的属性进行复制。

子类化的含义

如果我们将 ndarray 子类化,我们不仅需要处理数组类型的显式构造,还需要处理视图投影或
从模板创建。NumPy有这样的机制,这种机制使子类化略微不标准。

ndarray用于支持视图和子类中的从模板创建的机制有两个方面。

第一种是使用该ndarray.__new__方法进行对象初始化的主要工作,而不是更常用的__init__
方法。第二个是使用该__array_finalize__方法在模板创建视图和新实例后允许子类清理。

#一个简短的Python入门__new__和__init__

__new__是一个标准的Python方法,如果存在,__init__在我们创建类实例之前调用它。
有关更多详细信息,请参阅python __new__ 文档

例如,请考虑以下Python代码:

。。。。。。。。。。。。。

作者:柯广

篇幅有限更多请见扩展链接:http://www.mark-to-win.com/tutorial/52207.html

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章