2013-04-24 113 views
2

我試圖讓我的程序更快。 我有一個矩陣和一個向量:Python Newaxis vs for循環

GDES = N.array([[1,2,3,4,5], 
[6,7,8,9,10], 
[11,12,13,14,15], 
[16,17,18,19,20], 
[21,22,23,24,25]]) 
Ene=N.array([1,2,3,4,5]) 
NN=len(GDES); 

我已經定義了一個函數用於矩陣乘法:

def Gl(n,np,k,q): 
    matrix = GDES[k,np]*GDES[k,n]*GDES[q,np]*GDES[q,n] 
    return matrix 

和我在我的計算由一個for循環:

SIl = N.zeros((NN,NN),N.float) 
for n in xrange(NN): 
    for np in xrange(NN): 
     SumJ = N.sum(N.sum(Gl(n,np,k,q) for q in xrange(NN)) for k in xrange(NN)) 
     SIl[n,np]=SumJ 

print 'SIl:',SIl 

輸出:

SIl: [[ 731025. 828100. 931225. 1040400. 1155625.] 
[ 828100. 940900. 1060900. 1188100. 1322500.] 
[ 931225. 1060900. 1199025. 1345600. 1500625.] 
[ 1040400. 1188100. 1345600. 1512900. 1690000.] 
[ 1155625. 1322500. 1500625. 1690000. 1890625.]] 

我想用newaxis,使其更快:

def G(): 
    Mknp = GDES[:, :, N.newaxis, N.newaxis] 
    Mkn = GDES[:, N.newaxis, :, N.newaxis] 
    Mqnp = GDES[:, N.newaxis, N.newaxis, :] 
    Mqn = GDES[N.newaxis, :, :, N.newaxis] 
    matrix=Mknp*Mkn*Mqnp*Mqn 
    return matrix 

tmp = G() 
MGI = N.sum(N.sum(tmp,axis=3), axis=2) 
MGI = N.reshape(MGI,(NN,NN)) 
print 'MGI:', MGI 

輸出:

MGI: [[ 825 3900 9225 16800 26625] 
[ 31200 92400 169600 262800 372000] 
[ 146575 413400 722475 1073800 1467375] 
[ 403200 1116900 1911600 2787300 3744000] 
[ 857325 2352900 3980725 5740800 7633125]] 

任何想法,我怎麼能得到正確的答案?

+2

請不要喊。 – 2013-04-24 22:08:20

回答

4

你的問題是np.einsum一個完美的結合:

>>> GDES = np.arange(1, 26).reshape(5, 5) 
>>> np.einsum('kj,ki,lj,li->ij', GDES, GDES, GDES, GDES) 
array([[ 731025, 828100, 931225, 1040400, 1155625], 
     [ 828100, 940900, 1060900, 1188100, 1322500], 
     [ 931225, 1060900, 1199025, 1345600, 1500625], 
     [1040400, 1188100, 1345600, 1512900, 1690000], 
     [1155625, 1322500, 1500625, 1690000, 1890625]]) 

爲了您的具體情況下,其它語法可能會更容易弄清楚:

>>> np.einsum(GDES, [2,1], GDES, [2,0], GDES, [3,1], GDES, [3,0], [0,1]) 
array([[ 731025, 828100, 931225, 1040400, 1155625], 
     [ 828100, 940900, 1060900, 1188100, 1322500], 
     [ 931225, 1060900, 1199025, 1345600, 1500625], 
     [1040400, 1188100, 1345600, 1512900, 1690000], 
     [1155625, 1322500, 1500625, 1690000, 1890625]])