2017-08-28 44 views
2

我有三個矩陣WHV。我想得到keep,它存儲V的所有列和W的每列之間的元素乘法,並逐行進行。是否有可能將矩陣A中的每列與矩陣B的每列相乘而不是for循環?

V具有6行,W也有6行。的W每一列(其具有6個元件),用6個元素相乘的V柱逐列中的每個柱。然後總結由行結果)

W = np.random.randint(4,6, size=(6, 4)) 
H = np.random.randint(1,3, size=(4, 5)) 
V = np.dot(W,H) + 1  
keep = np.array([]).reshape(0,6) 

print W 
>>[[4 4 5 5] 
[4 4 4 4] 
[4 5 5 4] 
[4 5 5 5] 
[5 4 4 5] 
[5 4 4 5]] 
print V 
>>[[28 33 32 37 24] 
[25 29 29 33 21] 
[28 33 33 37 24] 
[30 35 34 39 25] 
[28 32 32 37 23] 
[28 32 32 37 23]] 

# I want the result from only two from four rows of W 
group = 2 
for k in xrange(group): 
    # multiply all of each column of V by k-th column of W and sum in row 
    keep = np.vstack([keep, sum(V[:,:].T*W[:,k])]) 

print keep, keep.shape 
>>[[ 616. 548. 620. 652. 760. 760.] 
    [ 616. 548. 775. 815. 608. 608.]] (2L, 6L) 

我不知道這可以做到沒有for循環?像sum(V[:,:].T*W[:,0:1]雖然,我不認爲這是可能的,因爲W的每一列都必須逐步增加矩陣V,我相信有人有更好的主意(或確認它不能)。

我儘量避免for循環,因爲這是長算法的一部分,我希望當group達到數百時,它可以超快。

回答

2

似乎是一個非常適合np.einsum,因爲我們需要在保持兩個輸入端之間對準的第一軸,並保持它的輸出 -

np.einsum('ij,ik->ki',V,W) 

採樣運行 -

In [2]: W = np.random.randint(4,6, size=(6, 4)) 
    ...: H = np.random.randint(1,3, size=(4, 5)) 
    ...: V = np.dot(W,H) + 1  
    ...: keep = np.array([]).reshape(0,6) 
    ...: 

In [5]: group = W.shape[1] 
    ...: for k in xrange(group): 
    ...:  # multiply all of each column of V by k-th column of W and sum in row 
    ...:  keep = np.vstack([keep, sum(V[:,:].T*W[:,k])]) 
    ...:  

In [6]: np.allclose(keep, np.einsum('ij,ik->ki',V,W)) 
Out[6]: True 
+1

哇!以前從未知道這一點。你介意下箭頭之間的箭頭解釋一下嗎?如果我不想使用所有的矩陣,我只是定義像'np.einsum('ij,ik-> ki',V,W [:,0:2])'? – Jan

+1

@Jan ['This comment'](https://stackoverflow.com/questions/45896939/using-python-numpy-einsum-to-obtain-dot-product-between-2-matrices/45896957#comment78752868_45896957)可能會有所幫助瞭解下標符號。是的,如果你只有'W'的前兩列,'np.einsum('ij,ik-> ki',V,W [:,0:2])'應該可以工作。 – Divakar

+0

非常感謝。讓我再問一件事。如果在'keep'之前'sum',我有一個分母; 'keep = np.vstack([keep,sum((VT * W [:,k])。T/deno)])'where'deno = np.dot(W,H)'('keep'必須改爲'keep = np.array([])。reshape(0,5)')。如何在'np.einsum'中輸入分母?或者如果我有分裂,我必須使用其他東西? – Jan

相關問題