2013-09-23 9 views
6

पर कैसे धक्का देना है मेरे पास कोड का निम्नलिखित भाग है जो मैं चाहता हूं (यह एक क्रिंग विधि का हिस्सा है)। लेकिन समस्या यह है कि यह बहुत धीमी हो जाती है, और मैं जानना चाहता हूं कि फॉर-लूप को कम करने के लिए कोई विकल्प है या नहीं? अगर मैं numpy.sum को दबाता हूं, और धुरी तर्क का उपयोग करता हूं, तो यह थोड़ा सा गति करता है, लेकिन स्पष्ट रूप से यह बाधा नहीं है। मैं कैसे नीचे forloop धक्का कर सकते हैं पर कोई भी विचार यह इसकी गति बढ़ाने के लिए NumPy के लिए, या यह इसकी गति बढ़ाने के लिए अन्य तरीकों से?)फॉर-लूप को numpy

# 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) 

मैं बाहर कुछ सामान

स्पष्ट करने के ndarrays n मैट्रिक्स के आयामों तैनात

संपादित करें: वी.वी. के आकार 2116

+1

क्या आकार है ' VV'? –

+0

यदि 'वीवी.शिप == (1630 9,)', तो आप इसे 'ईवीवी [: एन, 0]' द्वारा कैसे जोड़ सकते हैं जिसमें आकार '(एन,) 'है? – askewchan

+0

हो सकता है कि आपके लूप की आखिरी पंक्ति में 'ईवीवी [: एन, 0] * वीवी [के]' होना चाहिए, जो कि जैम का जवाब मानता है। – askewchan

उत्तर

5

आप कश्मीर पर अपने पाश के स्थान पर निम्नलिखित कर सकता है (क्रम ~ 3s):

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

यह @ usethedeathstar के कोड के समान परिणाम देता है, और मेरी मशीन पर 15x तेज चलता है। – askewchan

+1

'np.multiply' प्रसारण के रूप में, टाइल कॉल की कोई आवश्यकता नहीं है। इसे बदलें: 'VVg1 = np.sum (np.multiply (EVV1 [: n,:], VV [:, np.newaxis]), अक्ष = 0)' एक छोटी गति के लिए। – askewchan

+0

+1 अच्छी कॉल .... मैंने ऊपर की रेखा संपादित की है ... धन्यवाद –

3

है आप मूल रूप से, GRZVV की प्रत्येक पंक्ति के ले जा रहे हैं अंत में एक 1 जोड़कर, GinvVV साथ यह गुणा, तो वेक्टर के सभी तत्वों को जोड़कर।

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

या यहाँ तक कि: आप "जोड़ना 1" बात नहीं कर रहे थे, तो आप यह सब के रूप में कोई छोरों के साथ कर सकता

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

हम कैसे निपटेंगे कि अतिरिक्त 1? खैर, मैट्रिक्स गुणा से आने वाले परिणामी वेक्टर को GinvVV[:, -1] में इसी मान से बढ़ाया जाएगा, और जब आप उन्हें सभी जोड़ते हैं, तो मूल्य np.sum(GinvVV[:, -1]) द्वारा बढ़ाया जाएगा। तो हम बस एक बार इस की गणना और वापसी वेक्टर में सभी आइटम में जोड़ सकते हैं:

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

ऊपर कोड काम करता है VV एक अदिश है। यदि यह आकार (n,) की एक सरणी है, तो निम्नलिखित काम करेगा:

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

@ usethedeathstar के संपादन के साथ, 'वीवी.शिप' अब 2116 है, इसलिए आपके समाधान में प्रसारण नहीं होता है (क्योंकि' Wg.shape' 1630 9 है) – askewchan

+0

अनुमान लगाया कि यह एक स्केलर था। एक पूर्ण सरणी के साथ, अंत तक सरणी को ध्वस्त नहीं कर रहा है, जैसा कि जोएल के उत्तर में, बड़े सरणी के लिए उपरोक्त की तुलना में बहुत तेज़ है। – Jaime