私は5,000,000の整数リストを持っています。そして、私はリストを数が少ない配列にすることを望んでいます。私は次のコードを試しました:numpy.array(リスト)が遅い
numpy.array(list)
非常に遅いです。
この操作を100回ベンチマークし、リストを100回ループします。それほど大きな違いはありません。
どのようにすればよいでしょうか?
私は5,000,000の整数リストを持っています。そして、私はリストを数が少ない配列にすることを望んでいます。私は次のコードを試しました:numpy.array(リスト)が遅い
numpy.array(list)
非常に遅いです。
この操作を100回ベンチマークし、リストを100回ループします。それほど大きな違いはありません。
どのようにすればよいでしょうか?
あなたはdefinetly高速である関数を作成することができます。しかしただの警告:あなたのリストの中に無効な要素(整数でないか、大きすぎる整数)があると、クラッシュします。
私はIPythonの魔法がここ(%load_ext cython
と
%%cython
)、ポイントは、関数がどのように見えるかを示すためにされて使用
- 「ハウツー・コンパイル」のドキュメントあなたはCythonコードをコンパイルする方法を示していない(それは難しいことではありませんし、Cythonsかなり良いです)。
%load_ext cython
%%cython
cimport cython
import numpy as np
@cython.boundscheck(False)
cpdef to_array(list inp):
cdef long[:] arr = np.zeros(len(inp), dtype=long)
cdef Py_ssize_t idx
for idx in range(len(inp)):
arr[idx] = inp[idx]
return np.asarray(arr)
そしてタイミング:
import numpy as np
def other(your_list): # the approach from @Damian Lattenero in the other answer
ret = np.zeros(shape=(len(your_list)), dtype=int)
np.copyto(ret, your_list)
return ret
inp = list(range(1000000))
%timeit np.array(inp)
# 315 ms ± 5.42 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.array(inp, dtype=int)
# 311 ms ± 2.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit other(inp)
# 316 ms ± 3.97 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit to_array(inp)
# 23.4 ms ± 1.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
だから、10倍以上高速です。
このパフォーマンスの向上により、35fpsのビデオを処理できるようになりました。最も重要なことに、C++で数千行のコードを書き直す必要はありません。 – Yinan
私のMacでは約5倍の速さですが。 – Yinan
@Yinanまた、 'numpyをnpとし、' numpyをnpとしてインポートするだけでなく、 'np.uint8_t [:] arr = np.zeros(len(inp)、dtype = np.uint8) ')。操作は基本的に帯域幅が制限されているため、できるだけ小さいdtypeを選択することでこれを大幅に高速化できます。私はウィンドウを使用しているので、 'int32'はMacではおそらく' int64'なので、なぜあなたのものが第2因子より遅く見えるのか説明できます。あなたの「数字」は2倍の長さです。 – MSeifert
は、私は時間をチェックし、これが速いと思う:あなたはcythonを持っている場合は
import numpy as np
import time
start_time = time.time()
number = 1
elements = 10000000
your_list = [number] * elements
ret = np.zeros(shape=(len(your_list)))
np.copyto(ret, your_list)
print("--- %s seconds ---" % (time.time() - start_time))
--- 0.7615997791290283 seconds ---
リスト全体を高速にループするのはなぜですか? – Yinan
@ user3201090 'ret'がすでに割り当てられていて、適切な形でコピーが再配置されていないと言うのは、これが速い理由です。 –
@SeverinPappadeux、OPは前回の試行について話しています。ループ –
小さな整数の大きなリストを作成します。 numpy
松葉杖を使用:指定DTYPE
In [623]: arr8 = np.array(alist, 'uint8')
In [624]: timeit arr8 = np.array(alist, 'uint8')
1 loop, best of 3: 508 ms per loop
の配列を作成します
In [622]: timeit [i for i in alist]
10 loops, best of 3: 193 ms per loop
を(何もしない)プレーンなリストの反復の
In [619]: arr = np.random.randint(0,256, 5000000)
In [620]: alist = arr.tolist()
In [621]: timeit alist = arr.tolist() # just for reference
10 loops, best of 3: 108 ms per loop
と時間を私たちはして2倍の改善を得ることができますfromiter
;明らかにチェックは少なくなります。 np.array
は、リストが数字と文字列の組み合わせであっても機能します。それはまた、我々は全部渡って計算を行う際のアレイでの作業の利点が明らかになり、リストのリストなどに
In [625]: timeit arr81 = np.fromiter(alist, 'uint8')
1 loop, best of 3: 249 ms per loop
を処理します。
In [628]: timeit arr8.sum()
100 loops, best of 3: 6.93 ms per loop
In [629]: timeit sum(alist)
10 loops, best of 3: 74.4 ms per loop
In [630]: timeit 2*arr8
100 loops, best of 3: 6.89 ms per loop
In [631]: timeit [2*i for i in alist]
1 loop, best of 3: 465 ms per loop
よく配列で作業するよりも高速であることが知られていますかなりの「スタートアップ」オーバーヘッドがあることを示しています。
あなたのリストには整数のみが含まれていますか?結果の配列のdtypeは何ですか? – chrisb
ええ、私はそれについて非常に肯定的です。画像データのフラットな配列です。入力と出力の両方の配列はuint8タイプです – Yinan
@ user3201090私は私の答えを更新しました、previusは速くなかった、これは –