Nel mio previous question, ho imparato a ridimensionare una sottoclasse ndarray
in posizione. Neat. Purtroppo, che non funziona più quando la matrice che sto cercando di ridimensionare è il risultato di un calcolo:Trasferimento proprietà di dati numpy
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)
L'uscita esatta (compresi traceback) è:
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
Penso che questo sia perché numpy
crea un nuovo ndarray
e lo passa a __array_prepare__
. Tuttavia, a un certo punto lungo la strada, sembra che la matrice "" ottiene view-casted to my Foo
type, anche se i documenti non sembrano essere al 100% chiari/precisi su questo punto. In ogni caso, dopo il casting della vista, l'output non possiede più i dati rendendo impossibile rimodellarlo sul posto (per quanto ne so).
C'è un modo, tramite una sorta di numpy voodoo (__array_prepare__
, __array__
) ecc. Per trasferire la proprietà dei dati all'istanza della mia sottoclasse?
Su ulteriore ricerca, questo utente sembra essere [chiedendo la stessa cosa] (http://stackoverflow.com/questions/8708758/can- i-force-a-numpy-ndarray-to-take-ownership-of-its-memory), anche se da una prospettiva diversa ... È possibile che ci possa essere una risposta che funziona nella mia situazione che non funzionerebbe lì ... – mgilson
È certamente una vista. La base 'ndarray' è' d.base', che possiede i dati. Come kludge puoi ridimensionare 'd.base' e quindi riassegnare' d = d.base.view (Foo) '. – eryksun
eryksun - suoni promettenti tranne che poi potrei perdere gli altri attributi che ho aggiunto al mio campo nel frattempo. Pubblica comunque come risposta. Mi darà qualcosa per sperimentare domani. Sono un po 'troppo stanco per tentare qualcosa di più che un commento senza senso del mio codice a questo punto. – mgilson