74

範囲式で大きな配列を反復処理する場合、最高のパフォーマンスを得るにはrange、Python の組み込み関数または numpyを使用する必要がありますか?arange

これまでの私の推論:

rangeおそらくネイティブ実装に頼っているため、より高速になる可能性があります。一方、arangeメモリを占有する完全な配列を返すため、オーバーヘッドが発生する可能性があります。Python 3 の範囲式はジェネレータであり、すべての値をメモリに保持するわけではありません。

4

2 に答える 2

86

大きな配列の場合、ベクトル化された numpy 操作が最も高速です。ループする必要がある場合は、xrange/を優先rangeし、使用を避けてnp.arangeください。

numpy では、ベクトル化された計算、ufunc、およびインデックス作成の組み合わせを使用して、高速で実行される問題を解決する必要がありますC。numpy 配列のループは、これに比べて非効率的です。

(あなたができる最悪のことのようなものは、rangeまたはnp.arange質問の最初の文が示唆するように作成されたインデックスを使用して配列を反復処理することですが、あなたが本当にそれを意味するかどうかはわかりません.)

import numpy as np
import sys

sys.version
# out: '2.7.3rc2 (default, Mar 22 2012, 04:35:15) \n[GCC 4.6.3]'
np.version.version
# out: '1.6.2'

size = int(1E6)

%timeit for x in range(size): x ** 2
# out: 10 loops, best of 3: 136 ms per loop

%timeit for x in xrange(size): x ** 2
# out: 10 loops, best of 3: 88.9 ms per loop

# avoid this
%timeit for x in np.arange(size): x ** 2
#out: 1 loops, best of 3: 1.16 s per loop

# use this
%timeit np.arange(size) ** 2
#out: 100 loops, best of 3: 19.5 ms per loop

したがって、この場合、numpy を正しく使用すると、使用するよりも 4 倍高速になりxrangeます。問題によっては、numpy は 4 倍または 5 倍の高速化よりもはるかに高速になる場合があります。

この質問への回答では、大規模なデータ セットに Python リストの代わりに numpy 配列を使用する利点がいくつか説明されています。

于 2012-05-22T20:23:16.343 に答える
12

まず、@bmu が書いたように、ベクトル化された計算、ufunc、および indexing の組み合わせを使用する必要があります。確かに、明示的なループが必要な場合はいくつかありますが、それらは非常にまれです。

Python 2.6 および 2.7 で明示的なループが必要な場合は、xrangeを使用する必要があります(以下を参照)。あなたの言うことから、Python 3 では、rangeはxrangeと同じです(ジェネレーターを返します)。だから多分範囲はあなたにとって良いです。

ここで、自分で試してみてください (timeit を使用: - ここでは ipython の「魔法の関数」):

%timeit for i in range(1000000): pass
[out] 10 loops, best of 3: 63.6 ms per loop

%timeit for i in np.arange(1000000): pass
[out] 10 loops, best of 3: 158 ms per loop

%timeit for i in xrange(1000000): pass
[out] 10 loops, best of 3: 23.4 ms per loop

繰り返しますが、上記のように、ほとんどの場合、 ac speed: muchfast を実行する numpy ベクトル/配列式 (または ufunc など) を使用できます。これは、「ベクトル プログラミング」と呼ぶことができます。これにより、プログラムは C よりも実装が容易になります (そして読みやすくなります) が、最終的にはほぼ同じ速度になります。

于 2012-05-22T09:52:05.347 に答える