Numpy配列のastype()メソッドはあまり効率的ではないことがわかりました。 300万のUint8ポイントを含む配列があります。これに3x3行列を掛けるには2秒かかりますが、結果をuint16からuint8に変換するにはさらに1秒かかります。
より正確に :
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秒かかります
他の操作にかかる時間を考えると、astype
の方が速いと思います。型変換を行うためのより速い方法はありますか、それとも型変換がそれほど難しくないはずだと推測するときに私は間違っていますか?
編集:目標は、最後の8ビット配列をファイルに保存することです
imgarray = imgarray.astype('B')
を使用すると、配列のコピーを取得し、指定した型にキャストします。新しく割り当てられた配列を指すようにimgarrayをすぐに反転した場合でも、これには追加のメモリ割り当てが必要です。
imgarray.view('uint8')
を使用すると、配列のビューが表示されます。これは、_uint8
_ではなく_imgarray.dtype
_として解釈されることを除いて、同じデータを使用します。 (_np.dot
_は_uint32
_配列を返すため、_np.dot
_の後、imgarray
は_uint32
_型になります。)
ただし、view
を使用する場合の問題は、32ビット整数が4つの8ビット整数として表示され、最後の8ビットの値のみが考慮されることです。したがって、4番目ごとの8ビット整数にスキップする必要があります。スライスすることでそれを行うことができます:
imgarray.view('uint8')[:,::4]
IPythonの%timeitコマンドは、次の方法で処理が大幅に高速化されることを示しています。
_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
_