2014-02-18 94 views
2

我正在嘗試創建一個numpy.ndarray子類,它具有不同的屬性和更多的功能,這些屬性在我的應用程序中是必需的。 我仍然很難分配數據類型。具有新屬性的numpy.ndarray子類

class Vector(np.ndarray): 
    def __new__(cls, value, *args, **kwargs): 
     return np.asarray(value).view(cls) 

    def __init__(self, value, type=float): 
     self.set_type(type) 

    def set_type(self, type): 
     assert type in (int, float, complex, str), "type can only be int, float, complex or str, %r is given"%type 
     self.astype(type, copy=False) 

這表明該類型沒有變化

a = Vector([1,2,3], type=str) 
print a, a.dtype, a.type 
>> [1 2 3] int32 <type 'str'> 
+1

'astype'不會更改對象的內部類型。它會返回所需類型的副本。 –

+4

「ndarray」子類是一個無法逃脫的兔子洞。 OTOH,如果你*不*子類,那麼很多numpy函數分支的對象是否是'ndarray'將不會有相同的方式。結論:草莓奶昔反而! – DSM

+2

不要沉迷於讓你的代碼適合四人幫的設計模式。只要讓你的班級成爲'ndarray'的成員,並轉向有趣的問題。 – Cuadue

回答

0

您需要確保您的實例已在第一時間與正確dtype創建的,我的爲例。即期間__new__()。之後您不能更改dtype(除了創建新視圖或副本,但這不再是同一個實例)。

試試這個:

class Vector(np.ndarray): 
    def __new__(cls, data, dtype=None, copy=True): 
     return np.array(data, dtype=dtype, copy=copy).view(type=cls) 

    def __array_finalize__(self, obj): 
     assert issubclass(self.dtype.type, (np.number, np.character)), \ 
       "dtype can only be number or character, %s was given" % (self.dtype,) 

總是返回原始數據的副本,除非原ndarray雙方的dtype相同請求dtype(或者你把它在它的默認設置)copy=False

請注意,我將類型斷言放入__array_finalize__()方法中。這是爲了確保在所有3種情況下都會調用它:在創建np.ndarray.__new__(Vector, ...)的新實例Vector時,從另一個ndarray創建Vector類型的視圖以及切片Vector實例時。它將在所有3種情況下由numpy自動調用。如果你想斷言矢量是嚴格一維的,你也可以把它放到這個函數中。