2011-06-19 53 views
2

我想創建一個numpy.recarray的子​​類,當數據添加到當前長度以外的行時,它會自動調整大小。自動調整大小的NumPy recarray

下面的代碼可以完成我想要的大部分功能。

class autorecarray(numpy.recarray): 

    def __init__(self,*args,**kwargs): 
     self._increment = 1 
     numpy.recarray.__init__(self,args,kwargs) 

    def __setitem__(self,ind,y): 
     try: 
     numpy.recarray.__setitem__(self,ind,y) 
     except IndexError: 
     self.resize((self.__len__()+self._increment,),refcheck=False) 
     self.__setitem__(ind,y) 

它工作正常的這種使用情況:

a = utils.autorecarray((1,),formats=['i4','i4']) 
a[1] = (1,2) # len(a) will now be 2 

然而,這種用法將提高對numpy.core.records.recarray __getitem__方法的IndexError:

a[2]['f1'] = 3 

我最初的嘗試還要覆蓋我的子類中的__getitem__方法,但此代碼不起作用。

def __getitem__(self,ind): 
     try: 
     numpy.recarray.__getitem__(self,ind) 
     except IndexError: 
     self.resize((self.__len__() + self._increment,),refcheck=False) 
     self.__getitem__(ind) 

它不會自動擴展陣列,但現在的陣列中的每個產品None,不能改變。

誰能告訴我我做錯了什麼?

回答

3

首先你錯過了在numpy.recarray.__init__通話的星號:

def __init__(self, *args, **kwargs): 
    self._increment = 1 
    numpy.recarray.__init__(self, *args, **kwargs) 

第二,你錯過了在__getitem__return聲明:

def __getitem__(self,ind): 
    try: 
     return numpy.recarray.__getitem__(self,ind) 
    except IndexError: 
     self.resize((self.__len__() + self._increment,),refcheck=False) 
     return self.__getitem__(ind) 
+1

+1,'''','**'運算符很好。 – senderle

2

重寫的__getitem__不返回值。

我花了很長時間才意識到這一點。

此外,如Petr Viktorin指出,您在__init__調用中省略了***運營商。

+0

@bellamyj,我要補充我不一定推薦這種方法。你究竟想要做什麼? – senderle

+0

我有一些應用程序將輸出存儲在recarray中,但事先並不知道需要多少行。爲了避免違反DRY原則,這似乎是比檢查數組大小更好的解決方案,並且在我的代碼中的許多位置根據需要進行擴展。 – joshayers

+0

儘管如此,通過這種方式重寫getitem是危險的。如果您要檢索一個超出數組邊界的元素(而不是像上面的示例中那樣寫入),您將得到不正確的結果。我會堅持只有壓倒一切的setitem。 – joshayers