2013-07-31 49 views
6

我想要派生numpy ndarray的子​​類,但我無法正確使用其他numpy類型(如蒙版數組或矩陣)的操作。在我看來,__array_priority__沒有被尊重。作爲一個例子,我已經創建了一個模擬了重要方面的虛擬類:從numpy數組派生類與矩陣和蒙版陣列不能很好地發揮

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 

我的階級和正常 ndarray工作之間的操作預期:

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

但是,當我嘗試操作與矩陣(或屏蔽陣列)陣列優先不被尊重。

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

在我看來,ufuncs包裝矩陣和屏蔽陣列的方式並不尊重數組的優先級。是這樣嗎?有沒有解決方法?

+1

其實,給出錯誤消息,因爲它們沒有對齊,因爲'np.matrix((3, 3))'與np.asmatrix(np.ones((3,3)))'不一樣。但是,問題仍然存在,只是'm * c1'是不工作的。 –

+0

@GustavLarsson感謝您的發現。我修正了它,並在動機中增加了更多信息。 – Hernan

回答

2

一個解決辦法是子類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 

在這種情況下,優先級也越高則np.ndarray和你的乘法方法總是調用。

如添加註釋,您可以在情況下,從多個類的子類,你需要互操作性:

​​
+0

這很好用,但是我的類更好地由ndarray描述而不是矩陣。此外,我的班級應該與ndarray,矩陣和蒙面的darray進行互操作。有沒有辦法做到這一點? – Hernan

+0

嘗試使用這種方法,看看互操作是否實現,如果沒有,您可以從多個類繼承,例如:class C(np.matrixlib.defmatrix.matrix,np.ndarray):'。 .. –

+0

我已經將該類重新定義爲類C(np.matrixlib.defmatrix.matrix,np.ma.core.MaskedArray,np.ndarray):'。這是醜陋的,但它似乎工作,我仍然需要更多的測試用例。我現在正在試圖爲包裝數組的類(不帶子類)做同樣的事情。同樣,它可以在ndarray多重播放時正常工作,但不適用於其他任何情況。 – Hernan