2013-07-31 49 views
6

Tôi đang cố gắng phân lớp một mảng mờ nhưng tôi không thể thực hiện đúng các thao tác với các kiểu khác như mảng mặt nạ hoặc ma trận. Dường như với tôi rằng __array_priority__ không được tôn trọng. Như một ví dụ, tôi đã tạo ra một lớp giả rằng mimicks những khía cạnh quan trọng:Lớp có nguồn gốc từ mảng numpy không hoạt động tốt với ma trận và mảng bị che dấu

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 

Operations giữa lớp học của tôi và bình thường việc ndarray như mong đợi:

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

Tuy nhiên, khi tôi cố gắng để vận hành với ma trận (hoặc mảng mặt nạ) ưu tiên mảng không được tôn trọng.

>>> 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 

Dường như với cách mà các gói được bọc cho ma trận và mảng mặt nạ không được ưu tiên mảng ưu tiên. Đây có phải là trường hợp không? Có cách giải quyết nào không?

+1

Trên thực tế, thông báo lỗi được đưa ra vì họ không thẳng hàng, vì 'np.matrix ((3, 3)) 'không giống với' np.asmatrix (np.ones ((3, 3))) '. Tuy nhiên, vấn đề vẫn tồn tại, ngoại trừ 'm * c1' là một vấn đề không hoạt động. –

+0

@GustavLarsson Cảm ơn vì đã phát hiện ra điều đó. Tôi đã sửa nó và thêm thông tin vào động cơ. – Hernan

Trả lời

2

Một workaround là để phân lớp 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 

Trong trường hợp này ưu tiên cũng cao hơn sau đó một np.ndarray và phương pháp nhân của bạn luôn gọi.

Như bổ sung trong các ý kiến, bạn có thể phân lớp từ nhiều tầng lớp trong trường hợp bạn cần khả năng tương tác:

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

Điều này làm việc độc đáo, nhưng các lớp học của tôi được mô tả tốt hơn bởi ndarray hơn ma trận. Ngoài ra, lớp của tôi nên tương thích với các mảng ma trận, ma trận và mặt nạ. Có cách nào để đạt được điều này? – Hernan

+0

Hãy thử sử dụng cách tiếp cận này và xem sự tương tác có đạt được không, nếu không, bạn có thể phân lớp từ nhiều hơn một lớp, làm như: 'class C (np.matrixlib.defmatrix.matrix, np.ndarray):', ví dụ. .. –

+0

Tôi đã định nghĩa lại lớp là 'class C (np.matrixlib.defmatrix.matrix, np.ma.core.MaskedArray, np.ndarray):'. Đó là xấu xí nhưng nó có vẻ làm việc, tôi vẫn cần nhiều trường hợp thử nghiệm hơn. Bây giờ tôi đang cố gắng làm tương tự cho một lớp kết thúc tốt đẹp một mảng (không có phân lớp con). Một lần nữa, nó hoạt động tốt khi multipliying bởi một ndarray nhưng không cho bất cứ điều gì khác. – Hernan