2012-05-22 14 views
32

एक रेंज अभिव्यक्ति के साथ एक बड़ी सरणी पर पुनरावृत्ति करते समय, क्या मुझे पाइथन के अंतर्निहित रेंज फ़ंक्शन का उपयोग करना चाहिए, या सर्वोत्तम प्रदर्शन प्राप्त करने के लिए numpy's arange का उपयोग करना चाहिए?अंतर्निहित रेंज या numpy.arange: जो अधिक कुशल है?

मेरे तर्क अब तक:

arange शायद एक देशी कार्यान्वयन के लिए रिसॉर्ट्स और तेजी से इसलिए हो सकता है। दूसरी ओर, arange एक पूर्ण सरणी देता है, जो स्मृति पर कब्जा करता है, इसलिए एक ओवरहेड हो सकता है। पायथन 3 की रेंज अभिव्यक्ति एक जनरेटर है, जो स्मृति में सभी मानों को नहीं रखती है।

उत्तर

39

बड़े सरणी के लिए numpy तेज समाधान होना चाहिए।

numpy आप अपनी समस्याओं को हल करने के रूप में यह C गति से चलाता है vectorized गणना, ufuncs और indexing के संयोजन का उपयोग करना चाहिए

। numpy arrays पर लूपिंग इसकी तुलना में अक्षम है।

(सबसे बुरी बात आप range या np.arange के रूप में अपने प्रश्न में पहले वाक्य से पता चलता है के साथ बनाया एक सूचकांक के साथ सरणी पर पुनरावृति होगी कर सकता है की तरह कुछ है, लेकिन मुझे यकीन है कि यदि आप वास्तव में इसका मतलब यह नहीं कर रहा हूँ।)

import numpy as np 
import sys 

sys.version 
# out: '2.7.3rc2 (default, Mar 22 2012, 04:35:15) \n[GCC 4.6.3]' 
np.version.version 
# out: '1.6.2' 

size = int(1E6) 

%timeit for x in range(size): x ** 2 
# out: 10 loops, best of 3: 136 ms per loop 

%timeit for x in xrange(size): x ** 2 
# out: 10 loops, best of 3: 88.9 ms per loop 

# avoid this 
%timeit for x in np.arange(size): x ** 2 
#out: 1 loops, best of 3: 1.16 s per loop 

# use this 
%timeit np.arange(size) ** 2 
#out: 100 loops, best of 3: 19.5 ms per loop 
इस मामले numpy के लिए

तो 4 बार xrange का उपयोग कर अगर आप इसे सही कर की तुलना में तेजी है। आपकी समस्या के आधार पर numpy 4 या 5 बार की गति से बहुत तेज हो सकता है।

this question के उत्तरों बड़े डेटा सेट के लिए पायथन सूचियों के बजाय numpy arrays का उपयोग करने के कुछ और फायदे बताते हैं।

6

सबसे पहले, जैसा कि @bmu, द्वारा लिखा गया है, आपको वेक्टरकृत गणनाओं, यूफुनिक्स और इंडेक्सिंग के संयोजनों का उपयोग करना चाहिए। वास्तव में कुछ ऐसे मामले हैं जहां स्पष्ट लूपिंग की आवश्यकता होती है, लेकिन वे वास्तव में दुर्लभ हैं।

यदि स्पष्ट लूप की आवश्यकता है, तो पाइथन 2.6 और 2.7 के साथ, आपको xrange (नीचे देखें) का उपयोग करना चाहिए। आप जो कहते हैं, उससे पाइथन 3, रेंजxrange (जनरेटर लौटाता है) जैसा ही है। तो शायद रेंज आपके लिए उतनी ही अच्छी है।

अब, तुम यह कोशिश करनी चाहिए खुद (timeit का उपयोग कर: - यहाँ IPython "जादू समारोह"):

%timeit for i in range(1000000): pass 
[out] 10 loops, best of 3: 63.6 ms per loop 

%timeit for i in np.arange(1000000): pass 
[out] 10 loops, best of 3: 158 ms per loop 

%timeit for i in xrange(1000000): pass 
[out] 10 loops, best of 3: 23.4 ms per loop 

फिर, जैसा कि ऊपर उल्लेख किया है, समय की सबसे यह संभव numpy वेक्टर उपयोग करने के लिए है/सरणी सूत्र (या ufunc आदि ...) जो एसी गति चलाता है: बहुत तेज। यही वह है जिसे हम "वेक्टर प्रोग्रामिंग" कह सकते हैं। यह सी (और अधिक पठनीय) की तुलना में प्रोग्राम को कार्यान्वित करना आसान बनाता है लेकिन अंत में लगभग तेज़ है।

+0

धन्यवाद, मुझे जादू समारोह के बारे में पता नहीं था। – clstaudt

+3

एक मानक पायथन 'टाइमिट' मॉड्यूल है जो आईपीथन के बिना ऐसा करने की अनुमति देता है। लेकिन यह जादू कार्य का उपयोग करने के लिए बस इतना आसान है। –

+0

-1 क्योंकि मुझे लगता है कि यह एक अच्छा बेंचमार्क नहीं है। एक numpy सरणी पर लूपिंग अक्षम है। – bmu

संबंधित मुद्दे