In my previous question, I learned to resize a subclassed ndarray
in place. Neat. Unfortunately, that no longer works when the array that I am trying to resize is the result of a computation:
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)
The exact output (including traceback) is:
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
I think this is because numpy
creates a new ndarray
and passes it to __array_prepare__
. At some point along the way though, it seems that the "output
"
array gets view-casted to my Foo
type, although the docs don't seem to be 100% clear/accurate on this point. In any event, after the view casting, the output no longer owns the data making it impossible to reshape in place (as far as I can tell).
Is there any way, via some sort of numpy voodoo (__array_prepare__
, __array__
) etc. to transfer ownership of the data to the instance of my subclass?