我们可以使用NumPy中引入的NumPy的分配机制来编写与NumPy API兼容并提供NumPy功能的自定义实现的自定义n维数组容器,应用程序包括dask数组(分布在多个节点上的n维数组)和cupy数组(GPU上的n维数组 )。
下面示例的实用程序不常用,但说明了所涉及的概念。
我们自定义数组可以像这样实例化:
我们可以使用numpy.array或numpy.asarray转换为numpy数组,这将调用其_array_方法以获得标准numpy.ndarray。
如果我们使用numpy函数对arr进行操作,numpy将再次使用array接口将其转换为数组,然后以通常的方式使用该函数。
返回类型是标准的numpy.ndarray
我们如何通过这个函数传递我们自定义数组类型呢?NumPy允许一个类通过接口_array_ufunc和_array_function_以定义的方式处理计算。我们一次取一个_array_ufunc_。这个方法涵盖了通用函数(ufunc),这是一类函数,其中包括numpy.multiply和numpy.sin。
该_array_ufunc_接收:
1.ufunc,类似numpy.multiply
2.method,一个字符串,区分numpy.multiply(…)和类似的变体,如numpy.multiply.outer,numpy.multiply.accumulate等等。通常情况下,numpy.multiply(…),method==‘_call_’
3.inputs,可能是不同类型的混合物
4.kwargs,将关键字参数传递给函数
在下面示例中,我们将仅处理方法_call_
现在我们的自定义数组类型通过numpy函数传递。
在这一点上arr+3是行不通的
为了支持它,我们需要定义Python接口add、It等来分派给相应的ufunc,我们可以通过继承mixin来方便地实现这一点。
接下来我们来解决_array_function_。我们将创建字典,将NumPy函数映射到我们的自定义变体。
一个简洁的模式是定义一个装饰器实现,可以用来向已处理函数添加函数。
现在,我们为实现DiagonalArray编写NumPy函数。为了支持arr.sum()的用法,添加一个调用numpy.sum(self)的方法sum,并且均值也是如此。
如果我们尝试使用HANDLED_FUNCTIONS中未包含的任何NumPy函数,则NumPy会引发TypeError,指示不支持此操作。例如,链接两个DiagonalArrays不会产生另一个对角线数组,因此不支持它。
此外,sum和mean的实现不接受NumPy的实现所接受的可选参数。
我们可以选择使用numpy.asarray转换为普通numpy.ndarray,并以此出使用标准Numpy。
如果你想学习Python,但是找不到学习路径和资源,欢迎上指尖编程。