gpt4 book ai didi

python - 如何继承 numpy.ndarray 的子类

转载 作者:太空狗 更新时间:2023-10-30 00:08:19 26 4
gpt4 key购买 nike

我正在努力对我自己的 numpy.ndarray 子类进行子类化。我真的不明白问题出在哪里,希望有人解释在以下情况下出了什么问题,以及如何做我想做的事情。

我想要实现的目标:

我有一个 numpy.ndarry 的子类,它的行为符合我的要求(下面代码中的 A 类)。我想子类化 A(下面代码中的类 B),以便 B 包含附加信息(名称)和方法(修饰的 .simple_data 方法)。

案例一:

import numpy as np

class A(np.ndarray):

def __new__(cls,data):
obj = np.asarray(data).view(cls)
return obj

def __array_finalize(self,obj):
if obj is None: return

class B(A):

def __init__(self,data,name):
super(B,self).__init__(data)
self.name = name

@property
def simple_data(self):
return [data[0,:],data[:,0]]

if __name__ == '__main__':
data = np.arange(20).reshape((4,5))
b = B(data,'B')
print type(b)
print b.simple_data

运行这段代码会产生输出:

Traceback (most recent call last):
File "ndsubclass.py", line 24, in <module>
b = B(data,'B')
TypeError: __new__() takes exactly 2 arguments (3 given)

我假设这与 B 的构造中的“name”变量有关,并且由于 A 是 numpy.array 的子类,A 的 new 方法在 B 的 之前被调用>init 方法。因此,为了解决这个问题,我假设 B 还需要一个 new 方法来适本地处理附加参数。

我的猜测是这样的:

def __new__(cls,data,name):
obj = A(data)
obj.name = name
return obj

应该这样做,但是我如何更改 obj 的类?

案例二:

import numpy as np

class A(np.ndarray):

def __new__(cls,data):
obj = np.asarray(data).view(cls)
return obj

def __array_finalize__(self,obj):
if obj is None: return

class B(A):

def __new__(cls,data):
obj = A(data)
obj.view(cls)
return obj

def __array_finalize__(self,obj):
if obj is None: return

@property
def simple_data(self):
return [self[0,:],self[:,0]]

if __name__ == '__main__':
data = np.arange(20).reshape((4,5))
b = B(data)
print type(b)
print b.simple_data()

运行时输出为:

<class '__main__.A'>
Traceback (most recent call last):
File "ndsubclass.py", line 30, in <module>
print b.simple_data()
AttributeError: 'A' object has no attribute 'simple_data'

正如我所料,这让我感到惊讶:

<class '__main__.B'>
[array([0, 1, 2, 3, 4]), array([ 0, 5, 10, 15])]

我假设在 B.new() 中对 view() 的调用在某种程度上没有正确设置 obj 的类。为什么?

我对发生的事情感到困惑,如果有人能解释一下,我将不胜感激。

最佳答案

对于情况1,最简单的方法是:

class B(A):
def __new__(cls,data,name):
obj = A.__new__(cls, data)
obj.name = name
return obj

__new__ 实际上是一个静态方法,它以类作为第一个参数,而不是类方法,所以你可以直接用你想创建实例的类调用它。

对于Case 2view 不能就地工作,你需要将结果分配给一些东西,最简单的方法是:

class B(A):
def __new__(cls,data):
obj = A(data)
return obj.view(cls)

此外,您在 AB 中定义了相同的 __array_finalize__(可能只是打字错误)——您没有不需要那样做。

关于python - 如何继承 numpy.ndarray 的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7342637/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com