gpt4 book ai didi

python - 对 numpy ndarray 进行子类化时,如何正确修改 __getitem__?

转载 作者:太空狗 更新时间:2023-10-29 20:30:30 24 4
gpt4 key购买 nike

我正在尝试子类化 numpy 的 ndarray。在我的子类 MyClass 中,我添加了一个名为 time 的字段作为主数据的并行数组。

我的目标如下:假设我创建了一个 MyClass 实例,我们称它为 mc。我切片 mc,例如 mc[2:6],我希望生成的对象不仅包含正确切片的 np 数组,还包含相应切片的 time 数组。

这是我的尝试:

class MyClass(np.ndarray):
def __new__(cls, data, time=None):
obj = np.asarray(data).view(cls)
obj.time = time
return obj
def __array_finalize__(self, obj):
setattr(self, 'time', obj.time)
def __getitem__(self, item):
#print item #for testing
ret = super(MyClass, self).__getitem__(item)
ret.time = self.time.__getitem__(item)
return ret

这是行不通的。经过几个小时的折腾,我意识到这是因为当我调用mc[2:6]时,__getitem__实际上被调用了多次。首先,当它被调用时,item 变量正如预期的那样是 slice(2,6,None)。但是随后,包含 super(MyClass, self)... 的行再次调用同一个函数,大概是为了检索切片的各个元素。

问题是它为 __getitem__ 提供了一组奇怪的参数,总是负数。在 mc[2:6] 的示例中,它又调用了该方法 4 次,item 值为 -4、-3、-2 和 -1。

如您所见,这使我无法正确调整 ret.time 变量,因为它会多次尝试修改它,而且通常使用无意义的索引。

我已尝试通过多种方式解决此问题,包括复制对象并改为编辑该副本、获取对象的各种 View 以及许多其他技巧,但似乎没有一种方法可以解决 __getitem__ 使用与请求的切片不一致的负索引重复调用。

对于正在发生的事情的任何帮助或解释将不胜感激。

最佳答案

我有一个类似的问题,我使用 numpy matrix 解决了这个问题类为例。正如您在 __array_finalize__ 中创建数组之前所注意到的那样,__getitem__ 可以被多次调用。所以解决方案是将潜在的新索引存储在 __getitem__ 中,但将其设置在 __array_finalize__ 中。

class MyClass(np.ndarray):
def __new__(cls, data, time=None):
obj = np.asarray(data).view(cls)
obj.time = time
return obj
def __array_finalize__(self, obj):
setattr(self, 'time', obj.time)
try:
self.time = self.time[obj._new_time_index]
except:
pass

def __getitem__(self, item):
try:
if isinstance(item, (slice, int)):
self._new_time_index = item
else:
self._new_time_index = item[0]
except:
pass
return super().__getitem__(item)

关于python - 对 numpy ndarray 进行子类化时,如何正确修改 __getitem__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31282764/

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