私は多くの行列を追加しています。行列が[M1、M2 ...、M_n]であるとしましょう。簡単な方法は、X + = M、動作中numpyで行列加算を行う効率的な方法
X = np.zeros()
for M in matrices:
X += M
ある次に、PythonはX用の+ =が実行されるたびに新しいメモリを作成するのですか?そのような場合、それは非効率的なようです。 Xの新しいメモリを作成せずにインプレース操作を行う方法はありますか?
私は多くの行列を追加しています。行列が[M1、M2 ...、M_n]であるとしましょう。簡単な方法は、X + = M、動作中numpyで行列加算を行う効率的な方法
X = np.zeros()
for M in matrices:
X += M
ある次に、PythonはX用の+ =が実行されるたびに新しいメモリを作成するのですか?そのような場合、それは非効率的なようです。 Xの新しいメモリを作成せずにインプレース操作を行う方法はありますか?
これは動作しますが、より速く私のマシンではありません:あなたはMemoryErrorを取得しない限り
numpy.sum(matrices, axis=0)
、numpyの第二の推測のメモリ使用量にしようとすると努力する価値はありません。コンパイルされたコードを知っている開発者に任せてください。
しかし、私たちはいくつかの時間テストを行うことができます。それは本当に重要な問題ですね。
いいサイズのアレイを100回追加してテストします。第一の軸を横切る+ =
In [480]: %%timeit
...: X=np.zeros_like(M)
...: for _ in range(100): X+=M
...:
1 loop, best of 3: 627 ms per loop
またはサイズのアレイを作る(100、1000、1000)及び適用np.sum
と
In [479]: M=np.ones((1000,1000))
あなた反復アプローチ。
In [481]: timeit np.sum(np.array([M for _ in range(100)]),axis=0)
1 loop, best of 3: 1.54 s per loop
を使用し、np.add
ufuncを使用します。 reduce
では、リスト内のすべての値に順次適用できます。私はrange(1000)
を使用する場合
In [482]: timeit np.add.reduce([M for _ in range(100)])
1 loop, best of 3: 1.53 s per loop
np.sum
場合は私にMemoryErrorを与えます。私は(1000,1000,1000)配列を保持するのに十分なメモリがありません。リストから配列を作成するadd.reduce
と同じです。
通常、カバーの下にある+=
は隠されており、通常は私たちの心配はありません。しかし、カバーの下にピークをufunc.at
を見て:https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html#numpy.ufunc.at
オペランドの場所の操作でバッファなし実行「」「インデックス」で指定した要素のために。 ufuncを追加する場合、このメソッドは[indexes] + = bと同等ですが、複数回インデックスされた要素に対して結果が累積される点が異なります。
したがってX+=M
は、合計をバッファに書き込み、そのバッファをX
にコピーします。一時バッファがありますが、最終的なメモリ使用量は変わりません。 しかし、バッファの作成とコピーは高速なCコードで行われます。
np.add.at
バッファリングされたアクションがいくつかの問題(重複インデックス)を作成するケースを処理するために追加されました。
したがって、一時的なバッファは回避されますが、かなりのスピードのコストがかかります。おそらくそれを遅くする追加されたインデックス機能です。 (もっと公平なadd.at
テストがあるかもしれませんが、確かにこの場合は役に立ちません。)
In [491]: %%timeit
...: X=np.zeros_like(M)
...: for _ in range(100): np.add.at(X,(slice(None),slice(None)),M)
1 loop, best of 3: 19.8 s per loop
「[M1、M2 ...、M_n]」とまったく同じですか?それは配列のリストですか?それのサンプルを追加しますか? – Divakar
@Divakar私はそれが行列のリストだと思う。 – TuanDT
@Divakar、Mはnp.ndarrayです。 – DSKim