2016-10-31 4 views
2

NumPyでnp.dot()を使って行列乗算を行っています。データセットが非常に大きいので、できるだけ全体的な実行時間を短縮したい、つまりできるだけ少ないnp.dot()製品を実行したいと考えています。Numpyの線形代数

具体的には、私の値ベクトルの各要素からの全体の行列積と関連するフローを計算する必要があります。 NumPyでは、1つまたは2つのnp.dot()製品でこれらをすべて一緒に計算する方法はありますか? 以下のコードでは、np.dot()製品の数を減らして、同じ出力を得る方法はありますか?


import pandas as pd 
import numpy as np 

vector = pd.DataFrame([1, 2, 3], 
         ['A', 'B', 'C'], ["Values"]) 

matrix = pd.DataFrame([[0.5, 0.4, 0.1], 
         [0.2, 0.6, 0.2], 
         [0.1, 0.3, 0.6]], 
         index = ['A', 'B', 'C'], columns = ['A', 'B', 'C']) 

# Can the number of matrix multiplications in this part be reduced? 
overall = np.dot(vector.T, matrix) 
from_A = np.dot(vector.T * [1,0,0], matrix) 
from_B = np.dot(vector.T * [0,1,0], matrix) 
from_C = np.dot(vector.T * [0,0,1], matrix) 

print("Overall:", overall) 
print("From A:", from_A) 
print("From B:", from_B) 
print("From C:", from_C) 
+0

ここでの議論を参照してください - http://stackoverflow.com/questions/21562986/numpy-matrix-vector-multiplication –

+0

希望する入出力のより良い例を提供できますか?あなたが何を望んでいるかは明確ではありません。 –

+0

ここでは行列積を必要としません。私の答えを見てください。私はそれが現在選ばれているものよりも良いと思う。 –

答えて

1

ので、同様にあなたは、これらのスケーリング値の3 x 32D配列を定義し、マトリックス乗算を行うことができ -

scale = np.array([[1,0,0],[0,1,0],[0,0,1]]) 
from_ABC = np.dot(vector.values.ravel()*scale,matrix) 

サンプル実行 -

In [901]: from_A 
Out[901]: array([[ 0.5, 0.4, 0.1]]) 

In [902]: from_B 
Out[902]: array([[ 0.9, 1.6, 0.5]]) 

In [903]: from_C 
Out[903]: array([[ 0.8, 1.3, 1.9]]) 

In [904]: from_ABC 
Out[904]: 
array([[ 0.5, 0.4, 0.1], 
     [ 0.9, 1.6, 0.5], 
     [ 0.8, 1.3, 1.9]]) 

がここにありますnp.einsumで1つのステップですべてを行う代替 -

np.einsum('ij,ji,ik->jk',vector.values,scale,matrix) 

サンプル実行 -

In [915]: np.einsum('ij,ji,ik->jk',vector.values,scale,matrix) 
Out[915]: 
array([[ 0.5, 0.4, 0.1], 
     [ 0.9, 1.6, 0.5], 
     [ 0.8, 1.3, 1.9]]) 
+0

素早い対応に感謝します。これは非常に役に立ちます! – Andreas

+0

@アンドレアス助けになるのはうれしい! – Divakar

+0

'scale'はちょうど' np.eye(3) 'です。 – kennytm

2

あなたが行を選択するために使用するベクターは、実際に単位ベクトルである場合、あなたはfrom_Afrom_Bfrom_Cのために、すべての行列の乗算を行っていないオフにはるかに優れています。

from_ABC = matrix.values * vector.values 

あなただけoverallを取得するためにnp.dotへの単一の呼び出しが必要になります。行列の乗算は、あなただけのベクトルの対応するエントリのITによって、行列の各行を乗算する必要があるよりも多くの加算と乗算を必要とします。

+0

。 np.dotが*を使った単純な製品よりもはるかに遅いことを知っていると非常に役に立ちます。 – Andreas

+0

これは単なる操作量の問題です。私の製品は、matrix.size製品と合計がないようにブロードキャストします。ドットにはvector.size * matrix.sizeの積とmatrix.shape [0]の合計があります。 –

+0

私は、OPにスケーリング値を持つ最小のサンプルケースがあると仮定しましたが、OPが動作している実際の値であるようです。だから、これは良いことだ! @Divakar。 – Divakar

関連する問題