NumPy基础-子类化ndarray

子类化的ndarray相对简单,但是与其它Python对象相比,它却更复杂一点。

ndarrays和对象创建

ndarray的子类化很复杂,因为ndarray类的新实例可以通过三种不同的方式产生。

1.显示的构造函数调用在MySubClass(params),这是创建Pythton实例的常用方法。

2.视图转换,将现有的ndarray转换为给定的子类

3.模板新功能,从模板实例创建新实例,包括从子类化的数组返回切片,从ufunc创建返回类型以及复制数组。

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

视图转换

视图强制转换是标准的ndarray机制,通过这种机制,我们可以获取任何子类的ndarray,并返回数组的视图作为另一个(指定的)子类。



从模板创建新的

当NumPy发现它需要从模板实例创建一个新实例时,ndarray子类的新实例也可以通过与查看类型转换非常相似的机制来实现,这种情况最明显的地方是在获取子类数组的切片时。


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

在使用ndarray的其它地方,我们会用到这样的视图,比如复制数组(c_arr.copy()),创建ufunc输出数组,以及减少方法(c_arr.mean())。

向现有数组添加属性

使用已存在的标准ndarray的类,将其强制转换为我们的类型,并添加一个额外的属性。


所以:



子类化和下游兼容性

当子类化ndarray或创建模仿ndarray接口的duck类型时,你应决定api将如何与NumPy的api保持一致。为了方便起见,许多具有相应ndarray方法的NumPy函数(如,sum、mean、take、recapay)通过检查函数的第一个参数是否具有相同名称的方法来工作。如果存在则调用该方法,而不是将参数强制转换为NumPy数组。

例如,如果你希望你的子类或duck_type与NumPy的sum函数兼容,那么这个对象的sum方法的方法签名应该如下所示:


这与np.sum完全相同的方法签名,因此,如果我们现在在此对象上调用np.sum,则NumPy将调用该对象自己的sum方法,并将上述列举的参数传入签名中,并且不会引发错误,因为签名彼此完全兼容。

但是,如果你决定偏离此签名并执行以下操作:


则该对象不再与np.sum兼容,因为如果调用np.sum,它将传入意外的参数out和keepdims,从而引发TypeError。

如果你想学习Python,但是找不到学习路径和资源,欢迎上指尖编程。

你可能感兴趣的:(NumPy基础-子类化ndarray)