2013-07-31 12 views
6

Próbuję podklasy numpy ndarray, ale nie jestem w stanie uzyskać prawo operacji z innymi typami numpy, takich jak maskowana tablica lub macierz. Wydaje mi się, że __array_priority__ nie jest honorowany. Jako przykład, mam stworzył atrapę klasę, która naśladuje ważne aspekty:Wykreślona klasa z tablicy numpy nie gra dobrze z macierzą i maskowaną tablicą

import numpy as np 

class C(np.ndarray): 

    __array_priority__ = 15.0 

    def __mul__(self, other): 
     print("__mul__") 
     return 42 

    def __rmul__(self, other): 
     print("__rmul__") 
     return 42 

operacji pomiędzy moją klasą i normalnego ndarray pracy zgodnie z oczekiwaniami:

>>> c1 = C((3, 3)) 
>>> o1 = np.ones((3, 3)) 
>>> print(o1 * c1) 
__mul__ 
42 
>>> print(c1 * o1) 
__rmul__ 
42 

Jednak, gdy staram się działać z macierzą (lub maskowanymi tablicami) priorytet tablicy nie jest przestrzegany.

>>> m = np.matrix((3, 3)) 
>>> print(c1 * m) 
__mul__ 
42 
>>> print(m * c1) 
Traceback (most recent call last): 
... 
    File "/usr/lib64/python2.7/site-packages/numpy/matrixlib/defmatrix.py", line 330, in __mul__ 
    return N.dot(self, asmatrix(other)) 
ValueError: objects are not aligned 

Wydaje mi się, że sposób, w jaki ufuncs są pakowane dla macierzy i tablic z maskowaniem, nie uwzględnia priorytetu tablicowego. Czy tak jest? Czy jest w pobliżu praca?

+1

Faktycznie, pojawi się komunikat błędu, ponieważ nie są wyrównane, ponieważ 'np.matrix ((3, 3)) 'nie jest tym samym, co' np.asmatrix (np.ones ((3, 3))) '. Jednak problem nadal występuje, z tym że 'm * c1' jest tym, który nie działa. –

+0

@GustavLarsson Dzięki za to. Naprawiłem to i dodałem więcej informacji w motywacji. – Hernan

Odpowiedz

2

Jeden obejście jest podklasy np.matrixib.defmatrix.matrix:

class C(np.matrixlib.defmatrix.matrix): 

    __array_priority__ = 15.0 

    def __mul__(self, other): 
     print("__mul__") 
     return 42 

    def __rmul__(self, other): 
     print("__rmul__") 
     return 4 

W tym przypadku priorytetem jest również wyższa niż w np.ndarray i wasze metody mnożenia są zawsze dzwonił.

Jak dodał w komentarzach, można podklasy z wielu klas w przypadku trzeba interoperacyjność:

class C(np.matrixlib.defmatrix.matrix, np.ndarray): 
+0

To działa ładnie, ale moje klasy są lepiej opisane przez ndarray niż macierz. Dodatkowo moja klasa powinna współpracować z ndarray, matrix i maskray darray. Czy istnieje sposób, aby to osiągnąć? – Hernan

+0

Spróbuj użyć tego podejścia i sprawdź, czy osiągnięto współdziałanie, jeśli nie, możesz podklasować z więcej niż jednej klasy, wykonując np. 'Class C (np.matrixlib.defmatrix.matrix, np.ndarray):', na przykład. .. –

+0

Mam nową definicję klasy jako 'klasy C (np.matrixlib.defmatrix.matrix, np.ma.core.MaskedArray, np.ndarray):'. To jest brzydkie, ale wygląda na to, że nadal potrzebuję więcej przypadków testowych. Teraz próbuję zrobić to samo dla klasy, która owija tablicę (bez podklasy). Znowu działa dobrze, gdy jest multipliying przez ndarray, ale nie na nic innego. – Hernan

Powiązane problemy