gpt4 book ai didi

python - 更改子类 `ndarray` 就地 View

转载 作者:太空狗 更新时间:2023-10-29 17:08:33 26 4
gpt4 key购买 nike

假设我有一个简单的 Test 类,它继承自 numpy.ndarray ( documentation on ndarray subclassing )。此类创建一个对象,该对象是另一个 ndarray 的部分 View 。现在我想创建一个方法来就地修改这个 View 。像这样的东西:

import numpy


class Test(numpy.ndarray):

def __new__(cls, info='Test class'):
base = numpy.ndarray.__new__(cls, (6, 2), dtype=float)
view = base[0:2, :]
view.info = info
return view

def __array_finalize__(self, obj):
if obj is None:
return
self.info = getattr(obj, 'info', None)

def change_view(self, start, stop):
"""This is the method I'd like to implement"""
# Incorrect, but represents what I am looking for
self = self.base[start:stop]


if __name__ == '__main__':
t = Test()
print(t)
print(t.info)
t.change_view(1, 5)
print(t)
print(t.info)

我希望方法 .change_view(x) 修改 .base 属性的 View 以显示行 [1:5] 而不是 [0:2],它是 __new__() 中的默认值。

这可能吗?如果是这样,如何?否则,为什么不呢?请注意,.base 永远不会改变(它始终占用相同的内存空间),我只是想改变它的 View 。

注意事项

  • 请参阅 change_view() 中的注释。我知道 self = self.base[start:stop] 不正确,我知道并理解原因,但我认为这是表示我正在寻找的内容的简短方法。
  • 正如下面的答案所指出的,可以想到 self[:] = ...self.data = ...。但是,这在更改 View 大小时不起作用(确实如此)。

引用资料

这个问题was already asked here (或者至少是类似的情况),但答案指的是返回修改后的数组(即没有就地修改)或使用包装对象(即具有要修改的数组的属性)的解决方案。

我知道这些可能性,而且我知道它们可以更简单甚至更方便。但是,我想了解为什么(如果是的话)不可能做我正在寻找的事情。

最佳答案

1) 您不能就地更改 ndarray 实例或子类实例指向的数据。抱歉! 事实证明,可以就地更改 ndarray 实例指向的数据,但这是一个糟糕的主意,希望很快就会被删除:-)。参见 https://github.com/numpy/numpy/issues/7093

2) 您尝试像那样分配给 self 只会更改方法本地绑定(bind)中 self 变量的绑定(bind),恐怕这表明对 Python 的执行和对象模型如何工作的相当根本的误解。我之所以提出这个问题,是因为成功地对 ndarray 进行子类化是困难真的很难。近乎不可能。 (例如,流行的 pandas 库的开发人员放弃了。)尽管该文档给人以误导性印象,但 numpy 并不是真正设计用于支持子类化,而且它工作得不是很好。我通常建议根本没有人尝试子类化 ndarray;如果您还不是专业的 Python 程序员,那么这比这要多十倍。可能我们会删除那个愚蠢的页面并完全禁用子类化,除非它会破坏向后兼容性:-(。我建议找到一个不同的策略来解决你的问题。

关于python - 更改子类 `ndarray` 就地 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34896728/

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