В предыдущем вопросе , я научился изменять размер подкласса 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
"
array получает view-casted в мой Foo
тип, хотя документы не кажутся на 100% четкими/точными в этой точке. В любом случае, после каста представления, выход больше не владеет данными, что делает невозможным изменение на месте (насколько я могу судить).
Есть ли какой-либо способ с помощью какого-то numood voodoo (__array_prepare__
, __array__
) и т.д., чтобы передать право собственности на данные в экземпляр моего подкласса?