【发布时间】:2013-03-16 04:45:52
【问题描述】:
在我的previous question 中,我学会了调整子类ndarray 的大小。整洁的。不幸的是,当我尝试调整大小的数组是计算的结果时,这不再有效:
import numpy as np
class Foo(np.ndarray):
def __new__(cls,shape,dtype=np.float32,buffer=None,offset=0,
strides=None,order=None):
return np.ndarray.__new__(cls,shape,dtype,buffer,offset,strides,order)
def __array_prepare__(self,output,context):
print output.flags['OWNDATA'],"PREPARE",type(output)
return np.ndarray.__array_prepare__(self,output,context)
def __array_wrap__(self,output,context=None):
print output.flags['OWNDATA'],"WRAP",type(output)
return np.ndarray.__array_wrap__(self,output,context)
a = Foo((32,))
#resizing a is no problem
a.resize((24,),refcheck=False)
b = Foo((32,))
c = Foo((32,))
d = b+c
#Cannot resize `d`
d.resize((24,),refcheck=False)
确切的输出(包括回溯)是:
True PREPARE <type 'numpy.ndarray'>
False WRAP <class '__main__.Foo'>
Traceback (most recent call last):
File "test.py", line 26, in <module>
d.resize((24,),refcheck=False)
ValueError: cannot resize this array: it does not own its data
我认为这是因为numpy 创建了一个新的ndarray 并将其传递给__array_prepare__。不过,在某些时候,似乎“output”
数组得到view-casted to my Foo type,尽管在这一点上文档似乎不是 100% 清晰/准确。无论如何,在视图转换之后,输出不再拥有数据,因此无法就地重塑(据我所知)。
有什么方法可以通过某种 numpy voodoo(__array_prepare__、__array__)等将数据的所有权转移到我的子类的实例?
【问题讨论】:
-
在进一步搜索中,该用户似乎是asking the same thing,尽管从不同的角度来看......可能有一个适用于我的情况的答案,但在那里不起作用.. .
-
这当然是一个视图。基础
ndarray是d.base,它拥有数据。作为一个组合,您可以调整d.base的大小,然后重新分配d = d.base.view(Foo)。 -
eryksun -- 听起来很有希望,但我可能会失去同时添加到我的领域的其他属性。无论如何,将其发布为答案。明天它会给我一些实验的东西。在这一点上,除了盲目地评论我的代码之外,我有点太累了。
-
它可能会有所帮助,但它不能回答问题。我可以通过调整标志和基数来强制使用 ctypes,但这既丑陋又脆弱。
-
要调整大小,您需要使用
refcheck=False。这会使当前的Foo视图无效,因此您需要一个新视图。