2012-05-04 10 views
5

Estoy tratando de subclase numpy 's ndarray clase, y he tenido algo de suerte. El comportamiento que me gustaría es casi el mismo que el example que figura en la documentación. Quiero agregar un parámetro name a la matriz (que uso para realizar un seguimiento de dónde provienen originalmente los datos).Mantener una subclase ndarray numpy como el valor de retorno durante una transformación. ¿Es seguro establecer __array_priority__?

class Template(np.ndarray): 
    """A subclass of numpy's n dimensional array that allows for a 
    reference back to the name of the template it came from. 
    """ 
    def __new__(cls, input_array, name=None): 
     obj = np.asarray(input_array).view(cls) 
     obj.name = name 
     return obj 

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

esto funciona, excepto que, como this question, Quiero cualquier transformación que implica mi subclase para volver otra instancia de mi subclase.

funciones veces numpy hacen devolver una instancia de Template:

>>> a = Template(np.array([[1,2,3], [2,4,6]], name='from here') 
>>> np.dot(a, np.array([[1,0,0],[0,1,0],[0,0,1]])) 
Template([[1, 2, 3], 
     [2, 4, 6]]) 

Sin embargo, a veces no lo hacen:

>>> np.dot(np.array([[1,0],[0,1]]), a) 
array([[1, 2, 3], 
     [2, 4, 6]]) 

En la pregunta he vinculado al anterior, se sugirió que el PO debe anular el método __wrap_array__ para la subclase. Sin embargo, no veo ninguna justificación en esto. En algunas situaciones, estoy obteniendo mi comportamiento esperado con el predeterminado __array_wrap__. The docs parecen sugerir que estoy corriendo en una situación en la que es de __array_wrap__ método que se llama debido a una mayor __array_priority__ valor el otro argumento:

Tenga en cuenta que la ufunc (np.add) ha llamado el método __array_wrap__ de la entrada con el valor más alto __array_priority__

Así que mi pregunta tiene un par de partes relacionadas. Primero: ¿puedo establecer el atributo __array_priority__ de mi subclase para que siempre se llame a su __array_wrap__? Segundo: ¿Es esta la mejor/más fácil manera de lograr mi comportamiento deseado?

Respuesta

0

Cuando dos objetos tienen el mismo __array_priority__:

>>> np.array([[1,0],[0,1]]).__array_priority__ 
0.0 
>>> a.__array_priority__ 
0.0 

Y sólo métodos de un objeto puede ser utilizado, el empate se resuelve mediante el uso de los métodos de la primera matriz/de objeto. (En su caso __array_wrap__)

Según la pregunta, parece que los métodos de su clase siempre deben preferirse, ya que son los mismos (por herencia) o anulados.

Así que solo subiría __array_priority__.

class Template(np.ndarray): 
    __array_priority__ = 1.0 (Or whichever value is high enough) 
    ... 

Después de hacer esto, sin importar dónde está el objeto de la plantilla en un cálculo. Sus métodos serán preferidos sobre los métodos de arreglos estándar.

Cuestiones relacionadas