2009-12-11 18 views
14

numpy配列のastype()メソッドはそれほど効率的ではありません。私は 3百万のUint8点を含む配列を持っています。それを3x3行列に掛けるには2秒かかりますが、結果をuint16からuint8に変換するのにもう1秒かかります。numpy:配列型を素早く変換する方法

より正確:

print time.clock() 
    imgarray = np.dot(imgarray, M)/255 
    print time.clock() 
    imgarray = imgarray.clip(0, 255) 
    print time.clock() 
    imgarray = imgarray.astype('B') 
    print time.clock() 

ドット積及びスケーリングが2秒を要する
クリッピングが200ミリ秒 型変換をとり、他の操作にかかる時間を考えると、1秒

をとり、Iはastypeを期待より速くなる。 タイプ変換を高速に行う方法はありますか、そのタイプ変換がそれほど難しいとは思わないときは間違っていますか?

編集:目標は、あなたがimgarray = imgarray.astype('B')を使用すると、指定した型にキャスト配列のコピーを、取得ファイル

+0

は、なぜあなたは再びuint16のに行くとする必要があります:

imgarray.view('uint8')[:,::4]

IPythonの%はtimeitコマンドは、大きな速度はこの方法は、物事をやってそこにあることを示していますか? 'M'をuint8の行列にすることは可能ですか?変換する必要はありません。 – u0b34a0f6ae

+0

ドット積の結果はuint8の範囲を超えます。もともと私は浮動小数点型M行列を使用していましたが、整数に行くと少し改善されると思いましたが、これは真実ではありません。 – shodanex

+0

おそらく、そのすべての時間がかかると、すべてのメモリロケーションにアクセスしています。修正するのは難しいと思う。 –

答えて

24

に、最終的な8ビット配列を保存することです。たとえimgarrayを直ちに反転させて新しく割り当てられた配列を指し示したとしても、余分なメモリ割り当てが必要になります。

imgarray.view('uint8')を使用すると、配列のビューが表示されます。これは、imgarray.dtypeの代わりにuint8と解釈される以外は、同じデータを使用します。 (np.dotuint32配列を返し、そうnp.dot後、imgarrayタイプuint32である。)

viewを使用に伴う問題は、しかし、32ビット整数は4 8ビット整数として見るようになることである、と我々最後の8ビットの値についてのみ注意してください。だから、4番目の8ビット整数ごとにスキップする必要があります。私たちは、そのスライスを行うことができます。

In [37]: %timeit imgarray2 = imgarray.astype('B') 
10000 loops, best of 3: 107 us per loop 

In [39]: %timeit imgarray3 = imgarray.view('B')[:,::4] 
100000 loops, best of 3: 3.64 us per loop 
+1

このビューをファイルに保存することができます – shodanex

+0

@shodanex:はい、np.save()を使用できます。 http://docs.scipy.org/doc/numpy-1.3.x/reference/generated/numpy.save.html – unutbu

+0

@ shodanexを参照してください。その他のフォーマットオプションについては、http://docs.scipy.org/docも参照してください。 /numpy-1.3.x/reference/routines.io.html – unutbu

関連する問題