2011-06-19 28 views
2

データを現在の長さ以外の行に追加するときに自動的にサイズ変更されるnumpy.recarrayのサブクラスを作成したいとします。NumPy再配列の自動サイズ変更

私が欲しいものは以下のコードです。

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[2]['f1'] = 3 

マイ初期:

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

しかし、この使用法はnumpy.core.records.recarray __getitem__方法についてはIndexErrorが発生します私のサブクラスで__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

私は、再配列で出力を格納するアプリケーションをいくつか持っていますが、必要な行の数を事前に知っていません。 DRYの原則に違反するのを避けるために、これは配列サイズをチェックし、コード全体の多くの場所で必要に応じて拡張するよりも優れた解決策のように思えました。 – joshayers

+0

このようにgetitemをオーバーライドすることは危険です。上記の例のように配列の境界の外にある要素を取得する場合は、誤った結果が得られます。私はsetitemをオーバーライドするだけに固執します。 – joshayers