2013-09-23 12 views
6

Ben tam olarak ne istediğimi yapan bir kod parçası var (bu bir kriging yönteminin bir parçasıdır). Ama sorun şu ki, çok yavaş ilerliyor, ve for-loop'u aşağıya itmek için herhangi bir seçenek olup olmadığını bilmek isterim? Eğer numpy.sum'u dışarı çıkarırsam ve oradaki eksen argümanını kullanırsam, biraz hızlanır, ama görünüşe göre bu darboğaz değildir. i forloop aşağı itebilir nasıl bir fikir bunu hızlandırmak için numpy için mi yoksa başka yolları da hızlandırmak için?)Geri döngü için aşağı itmek nasıl

# n = 2116 
print GRZVV.shape # (16309, 2116) 
print GinvVV.shape # (2117, 2117) 
VVg = numpy.empty((GRZVV.shape[0])) 

for k in xrange(GRZVV.shape[0]): 
    GRVV = numpy.empty((n+1, 1)) 
    GRVV[n, 0] = 1 
    GRVV[:n, 0] = GRZVV[k, :] 
    EVV = numpy.array(GinvVV * GRVV) # GinvVV is numpy.matrix 
    VVg[k] = numpy.sum(EVV[:n, 0] * VV) 

ben bazı şeyler

temizlemek için ndarrays n matris boyutları yayınlanmıştır

düzenleme: VV şekli temelde sonra vektör tüm unsurları ekleyerek, GRZVV her satırı alarak GinvVV ile çarpılarak, sonunda 1 sona eklendiğini 2116

+1

Ne şekildir ' VV'? –

+0

Eğer VV.shape == (16309,) 'ise, '(n,)' şeklindeki EVV [: n, 0] 'ile bunu nasıl ekleyebilirsin? – askewchan

+0

Belki de döngünüzün son satırı, @ Jaime'nin cevabının varsaydığı gibi görünen EVV [: n, 0] * VV [k] 'olmalıdır. – askewchan

cevap

5

Sen k üzerine döngü yerine aşağıdaki yapabileceğini (çalışma zamanı ~ 3 sn):

tmp = np.concatenate((GRZVV, np.ones((16309,1),dtype=np.double)), axis=1) 
EVV1 = np.dot(GinvVV, tmp.T) 
#Changed line below based on *askewchan's* recommendation 
VVg1 = np.sum(np.multiply(EVV1[:n,:],VV[:,np.newaxis]), axis=0) 
+1

Bu, @ usethedeathstar'ın koduyla aynı sonucu verir ve makinemde 15x daha hızlı çalışır. – askewchan

+1

“np.multiply” yayınları gibi döşeme çağrısına gerek yoktur. Bunu, küçük bir hız için 'VVg1 = np.sum (np.multiply (EVV1 [: n,:], VV [:, np.newaxis]), eksen = 0) 'olarak değiştirin. – askewchan

+0

+1 İyi bir çağrı .... Yukarıdaki satırı düzenledim ... teşekkürler –

3

olduğunu. Hatta

VVg = np.sum(np.dot(GinvVV[:, :-1], GRZVV.T), axis=-1) * VV 

ya: burada "1 eklemek" şeyi yapmıyor olsaydı, hiçbir döngüler ile tüm Yapabiliriz

VVg = np.einsum('ij,kj->k', GinvVV[:, :-1], GRZVV) * VV 

nasıl o ekstra 1 ele? Peki, matris çarpımından gelen sonuç vektörü, GinvVV[:, -1]'daki karşılık gelen değerle artırılacak ve hepsini eklediğinizde, değer np.sum(GinvVV[:, -1]) tarafından artırılacaktır. Yani biz sadece bir kez bu hesaplar ve dönüş vektörü tüm öğelere ekleyebilirsiniz: VV bir skaler ise

VVg = (np.einsum('ij,kj->k', GinvVV[:-1, :-1], GRZVV) + np.sum(GinvVV[:-1, -1])) * VV 

Yukarıdaki kod çalışır. o şekil (n,) dizisi ise, o şu çalışacaktır:

GinvVV = np.asarray(GinvVV) 
VVgbis = (np.einsum('ij,kj->k', GinvVV[:-1, :-1]*VV[:, None], GRZVV) + 
      np.dot(GinvVV[:-1, -1], VV)) 
+1

@ usethedeathstar'ın düzenlemesiyle, 'VV.shape' artık 2116, yani çözümünüzde yayınlamıyor (çünkü Wg.shape' 16309 – askewchan

+0

Figürlü bir skaler oldu. Dizinin sonuna kadar dizilmemesi, Joel'in cevabında olduğu gibi, tam diziyle, büyük diziler için yukarıdakilerden çok daha hızlıdır. – Jaime

İlgili konular