2013-07-02 12 views
6

私はn個の外側の製品の合計を計算するための速い方法を探しています。Python - 外側の商品を合計する速い方法は?

本質的に、私は正規分布から生成された2つの行列で始まる - V族元素のnベクトルがあります

A = np.random.normal(size = (n, v)) 
B = np.random.normal(size = (n, v)) 

私はたい何がAでサイズVの各ベクトルの外積を計算することですそれらを合算する。

A * B.Tが機能しないことに注意してください。Aはサイズn x vで、Bはサイズv x nです。

私ができることは、外側の製品が構築され、後で合計されるループを作成することです。私は同様にそれを持っている:

outers = np.array([A[i] * B[i].T]) 

これは私は、np.sum(outers, axis = 0)を使用して一緒に合計することができ、(ループが続いてアレイに変換されるリスト内包、内にある)、n個のXのV XのV配列を作成します。しかし、これはかなり遅く、私はこれを高速化するために使用できるベクトル化された関数があるのだろうかと思っていました。

誰かがアドバイスをお持ちでしたら、本当にありがとうございます。

答えて

7

私には、転位の順番を変えることだけが必要だと思われ、A * B.Tの代わりにA.T * Bをしてください。

これはあなたが何をしているのではない場合は、非常に強力なブードーを行うことができるnp.einsumを見てください。上記の例では、次のようにします。

np.einsum('ij,ik->jk', A, B) 
+0

エインサムは美しく動作します。ありがとう! – Adam

2

np.outerも考えてみましょう。 @Jamieによって提案np.einsumものの

np.array([np.outer(A, B) for i in xrange(n)]).sum(0) 

明確な勝者です。

In [63]: %timeit np.einsum('ij,ik->jk', A, B) 
100000 loops, best of 3: 4.61 us per loop 

In [64]: %timeit np.array([np.outer(A[i], B[i]) for i in xrange(n)]).sum(0) 
10000 loops, best of 3: 169 us per loop 

と、確かに、その結​​果は同じです:

In [65]: np.testing.assert_allclose(method_outer, method_einsum) 

しかし、余談として、私はA.T * BまたはA * B.Tが正常に放送することを見つけることはありません。

+0

彼は 'np.matrix'オブジェクトに' np.ndarray'sを掛けていません。 'A * B.T'は' np.dot(A、B.T) 'に、' A.T * B'は 'np.dot(A.T、B)'に相当します。それは 'np.einsum'に非常に近い時計でなければなりません。 – Jaime

+0

+1の2つの方法を比較すると – elaRosca

関連する問題