2016-04-25 2 views
6

私は、配列モジュールを使用して、符号なし32ビット整数のかなりの数(多くのギガバイト)を格納しています。各要素に4バイトを使用するのではなく、pythonはarray.itemsizeで示されるように8バイトを使用し、pymplerで検証します。Pythonの配列要素を特定のサイズにすることはできますか?

例:

>>> array("L", range(10)).itemsize 
8 

私は、要素の数が多いので、私は4つのバイト内でそれらを保存するの恩恵を受けるだろう。

numpyのは、私は符号なしの32ビットのint型として値を格納できるようになる

>>> np.array(range(10), dtype = np.uint32).itemsize 
4 

しかし、問題はnumpyののインデックス演算子を使用して、任意の操作があるということである約2倍遅い、ベクトル演算ではありません操作はサポートさそうnumpy分遅いです。 は、例えば:

python3 -m timeit -s "import numpy as np; a = np.array(range(1000), dtype = np.uint32)" "for i in range(len(a)): a[i]" 
10000 loops, best of 3: 90.4 usec per loop 

python3 -m timeit -s "from array import array; a = array('L', range(1000))" "for i in range(len(a)): a[i]" 
10000 loops, best of 3: 51.4 usec per loop 

だから私はに強制的にどちらか私は希望、またはプログラムは、私が希望の倍遅く実行されますの2倍のメモリを使用しています。これを回避する方法はありますか?私はPython配列を指定されたitemsizeを使用するよう強制できますか?

+0

https://bugs.python.org/issue26821 –

+0

これは間違った二分法です。プログラムのメモリ使用量が少なくて済み、高速です。異なるプラットフォーム上で固定サイズの 'array'アイテムを使うことができるかどうかという疑問とは無関係ですが(' array'はおそらくプラットフォーム固有のCタイプサイズを使用しています)。これは分離された質問です。具体的なnumpyベースの計算をより速くする方法です。 – jfs

答えて

5

あたり0.218マイクロ秒あなたはarrayを使用してに固執したい場合は、set the typecodeunsigned long)ではなくIunsigned int)になります。

>>> array.array("I", range(10)).itemsize 
4 

あなたがnumpyを使って失う2倍以上の計算方法をスピードアップする方法がないと、私は非常に驚くでしょう。それらの値で何をやっているのか正確に知らなくても、伝えにくいです。

1

2物事:numpy.arange()(内部メソッド)

を使用して、(コンピュータの速度の理由から)numpyのと文の使用は避けてください。放送技術を可能な限り使用してみてください。

すべての項目を取得する簡単な方法は、numpy配列の形が途中で崩れている場合に.ravel()を使用することです。

python3 -m timeit -s "import numpy as np; a = np.arange(1000), 
....... dtype = np.uint32)" "for i in range(len(a)): a[i]" 

10000ループ、3の最高:ループあたり106マイクロ秒

python3 -m timeit -s "import numpy as np; a = np.arange(1000), 
....... dtype = np.uint32)" "a.ravel()" 

1000000ループ、3の最高:ループ

1

表示されているように、herearray.arrayは(私の知る限り)特に興味のない古いツールです。

効率性の問題がある場合はarray.arrayよりnumpy.arrayが最適です。ベクトル化されたツールは数多く用意されています。この場合、32ビット演算でも64ビットシステム上で、多くの場合、64-ビットのものよりも速く、次のとおりです。

import numpy as np 
In [528]: %timeit np.sum(a32) 
1000 loops, best of 3: 1.86 ms per loop 

In [529]: %timeit np.sum(a64) 
100 loops, best of 3: 2.22 ms per loop 

In [530]: %timeit sum(a32) 
1 loop, best of 3: 572 ms per loop 

In [531]: %timeit sum(a64) 
1 loop, best of 3: 604 ms per loop 

見ての通り、あなたが遅い純粋なPythonのループを回避しなければなりません。

関連する問題