2014-01-08 77 views
0

我無法弄清楚如何使用CArray特徵。爲什麼這個類CArray初始化和賦值問題

from traits.api import HasTraits, CArray, Float,Int 
import numpy as np 

class Coordinate3D(HasTraits): 
    coordinate = CArray(Float(), shape=(1,3)) 

    def _coordinate_default(self): 
    return np.array([1.,2.,3.]) 

顯然不是用我的_name_default()方法?

In [152]: c=Coordinate3D() 
In [153]: c.coordinate 
Out[153]: np.array([[ 0., 0., 0.]]) 

我會期待np.array([1,2,3])!該_name_default()似乎與詮釋

class A(HasTraits): 
    a=Int 
    def _a_default(self): 
     return 2 

In [163]: a=A()  
In [164]: a.a 
Out[164]: 2 

工作所以我在做什麼錯在這裏?另外,我無法分配值:

In [181]: c.coordinate=[1,2,3] 
TraitError: The 'coordinate' trait of a Coordinate3D instance must be an array of  
float64 values with shape (1, 3), but a value of array([ 1., 2., 3.]) <type 
'numpy.ndarray'> was specified. 

相同的錯誤消息與

In [182]: c.coordinate=np.array([1,2,3]) 

回答

2

有一維陣列和二維陣列之間的差,其中所述尺寸中的一個具有尺寸1 。你正試圖將一維數組設置爲期望二維的CArray特性。例如,您的默認方法應該是:

def _coordinate_default(self): 
    return np.array([[1., 2., 3.]]) 

(請注意額外的方括號)。您正在設置的陣列形狀爲(3,),而不是所需的(1, 3)

同樣,它不會將一個扁平列表強制爲一個二維數組。嘗試分配一個嵌套列表,如

c.coordinate=[[1, 2, 3]] 

改爲。

(或者,如果你真的想1-d陣列,你應該在你的特質分配使用shape=(3,)和其他部分應能正常工作。)

+0

凱爾西,看到你的答案後,鍵入我自己的(咖啡休息時間沒有頁面刷新;-)。你是絕對正確的。 – Sven

0

假我。從Eclipse複製粘貼到iPython時,我沒有使用神奇的%paste功能,並在那裏搞亂了類定義。另一個實際的錯誤是CArray的形狀必須是(3,)。

此代碼

class Coordinate3D(HasTraits): 

    coordinate = CArray(Float(),shape=(3,)) 

    def __init__(self,iv=None): 
    super(Coordinate3D,self).__init__() 
    if iv: 
     self.coordinate=iv 

    def _coordinate_default(self): 
    return array([1,2,3]) 

    def __getitem__(self,index): 
    return self.coordinate[index] 

作品像預期:

In [3]: c=Coordinate3D() 
In [6]: c.coordinate 
Out[6]: array([ 1., 2., 3.]) 

In [7]: c=Coordinate3D([1,2,5]) 
In [8]: c.coordinate 
Out[8]: array([ 1., 2., 5.]) 

In [11]: c[0] 
Out[11]: 1.0 
0

在擴展到以前的答案,我再嘗試:

import types 
RealNumberType = (types.IntType, types.LongType, types.FloatType) 

class ScaleFactor3D(Coordinate3D): 
    '''Demonstrate subclassing a HasTraits class 
    and overriding __init__ and a _default method''' 
    def _coordinate_default(self): 
    return array([1,1,1]) 

    def __init__(self,iv=None): 
    if isinstance(iv,RealNumberType): 
     iv=[iv,iv,iv] 
    super(ScaleFactor3D,self).__init__(iv) 

這工作很順利:

In [35]: s=ScaleFactor3D() 

In [36]: s.coordinate 
Out[36]: array([ 1., 1., 1.]) 

In [37]: s=ScaleFactor3D(3) 

In [38]: s.coordinate 
Out[38]: array([ 3., 3., 3.]) 

我以爲我會把這個放在這裏,因爲我在網上找不到有關CArray的許多有用信息。