2013-02-19 180 views
2

我有以下的麻煩重塑:NumPy的ndarray子類 - 迫使__array_finalize__

我想編寫一個ndarray子類,併爲這一小類的任何新的實例執行形狀(-1,3),無論怎樣它來自於顯式構造函數,視圖轉換或來自模板。

我嘗試了大量的東西,但似乎沒有工作。 我覺得我還沒有完全掌握基本的過程。任何幫助深表感謝!

import numpy as np 

class test(np.ndarray): 
def __new__(cls, *args, **kwargs): 
    return np.ndarray.__new__(cls, *args, **kwargs) 

def __array_finalize__(self, obj): 

#  self.resize(-1,3) 
#  self.reshape(-1,3) 
#  self=self.reshape(-1,3) 
     np.reshape(self,(-1,3)) 

a=np.array([1,2,3]) 
b=a.view(test) 
c=test(a) 
d=a.reshape(-1,3) 
print '+++++++' 
print a.shape,a 
print '+++++++' 
print b.shape,b 
print '+++++++' 
print c.shape,c 
print '+++++++' 
print d.shape,d 

爲了澄清什麼,我試圖做的:

我有我想一般當作3D矢量場,因此(:3)的形狀和(1,3)形狀大小調整。我正在尋找一個純粹的面向對象的解決方案來實現基本上幾個額外的方法來補充已經與NumPy的。

舉例來說,我已經開始與ndarrays純粹的寫了一些東西,但代碼將更具可讀性,如果我可以只寫

normalizedVector = ndarray.view(my3DVectorClass).normalize() 

而不是

normalizedVector = ndarray/(sum(ndarray**2, axis=1)**0.5) 

我的問題第二個:

  • 我希望能夠不用擔心我是否要求準則(3,)或(:,3)數組的形狀化版本。
  • 我希望能夠使用純線性代數術語類方法實現內,沒有與索引和錯誤/法中尺寸檢查打擾定義

我猜你可能會說,只是一起工作只有my3DVectorClass的實例,但是當使用所有SciPy機器時,我必須做相反的視圖轉換,因爲如果我沒有弄錯他們會期望ndarray,這會使代碼的這些部分有點臃腫。

如果我可能有我的邏輯錯誤,我很感激的建議。我仍然在OOP和SciPy/NumPy的學習曲線上。

非常感謝!

馬庫斯

+0

您需要'__array_wrap__'等 – seberg 2013-02-19 23:13:20

回答

0

reshape將嘗試創建數據的視圖與新的形狀,如果它不能將創建數據的副本與新的形狀。但原始對象保持不變。如要修改的地方的形狀,你可以這樣做:

self.shape = (-1, 3) 

例如:

>>> a = np.arange(9) 
>>> a 
array([0, 1, 2, 3, 4, 5, 6, 7, 8]) 
>>> np.reshape(a, (-1, 3)) # creates a view with the new shape 
array([[0, 1, 2], 
     [3, 4, 5], 
     [6, 7, 8]]) 
>>> a # but the original object is unchanged 
array([0, 1, 2, 3, 4, 5, 6, 7, 8]) 
>>> a.shape = (-1, 3) # this modifies the original object 
>>> a 
array([[0, 1, 2], 
     [3, 4, 5], 
     [6, 7, 8]]) 

你必須要小心,因爲如果它不能在沒有製作副本重塑,這將提高一個AttributeError

>>> a = np.arange(36).reshape(6, 6).T 
>>> b = np.reshape(a, (-1, 3)) # creates a copy of the data in a 
>>> a.shape = (-1, 3) # tries to reshape in-place, and fails 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: incompatible shape for a non-contiguous array 
+0

非常感謝Jaime! – Markus 2013-03-01 12:38:23

7

你應該看看matrix class是如何實現的。它做類似的技巧來維護ndims=2

但是,我和其他許多人認爲這樣的詭計比它的價值更麻煩。 matrix課在過去已經引起了很多問題,因爲它只是部分地像ndarray那樣行事。考慮改寫功能。上面給出的代碼示例將是最可讀的,如下所示:normalizedVector = normalize(ndarray)。即使使用面向對象的風格,製作更多的子類並不總是最好的設計。

+0

嗨羅伯特,確實不是我希望聽到的,但你是真實的。功能是最終的直接解決方案。感謝您的建議! – Markus 2013-03-01 12:37:52