2011-12-28 11 views
7

मैं उलझन में हूं जब numpy के numpy.apply_along_axis() फ़ंक्शन एक साधारण पायथन लूप से बेहतर प्रदर्शन करेगा। उदाहरण के लिए, कई पंक्तियों के साथ एक मैट्रिक्स के मामले पर विचार करें, और आप प्रत्येक पंक्ति की राशि की गणना करना चाहते हैं:पायथन लूप की तुलना में numpy.apply_along_axis धीमी क्यों प्रतीत होता है?

x = np.ones([100000, 3]) 
sums1 = np.array([np.sum(x[i,:]) for i in range(x.shape[0])]) 
sums2 = np.apply_along_axis(np.sum, 1, x) 

यहाँ मैं भी उपयोग कर रहा हूँ एक अंतर्निहित numpy समारोह, np.sum, और अभी तक sums1 की गणना (पाइथन लूप) sums2 (apply_along_axis) की गणना करते समय 400ms से कम लेता है) 2000ms (विंडोज़ पर NumPy 1.6.1) लेता है। तुलना के आगे के तरीके से, आर की पंक्तिमैन फ़ंक्शन अक्सर 20ms से कम में यह कर सकती है (मुझे पूरा यकीन है कि यह सी कोड को कॉल कर रहा है) जबकि समान आर फ़ंक्शन apply() लगभग 600ms में ऐसा कर सकता है।

+0

दुर्भाग्य से अक्ष के साथ लागू केवल गैर गति प्रासंगिक कार्यों के लिए एक विकल्प प्रतीत होता है। – Wizard

उत्तर

10

np.sum, एक axis पैरामीटर ले ताकि आप योग बस

sums3 = np.sum(x, axis=1) 

का उपयोग कर यह 2 तरीकों आप उत्पन्न की तुलना में बहुत तेजी से होता है की गणना कर सकता है।

$ python -m timeit -n 1 -r 1 -s "import numpy as np;x=np.ones([100000,3])" "np.apply_along_axis(np.sum, 1, x)" 
1 loops, best of 1: 3.21 sec per loop 

$ python -m timeit -n 1 -r 1 -s "import numpy as np;x=np.ones([100000,3])" "np.array([np.sum(x[i,:]) for i in range(x.shape[0])])" 
1 loops, best of 1: 712 msec per loop 

$ python -m timeit -n 1 -r 1 -s "import numpy as np;x=np.ones([100000,3])" "np.sum(x, axis=1)" 
1 loops, best of 1: 1.81 msec per loop 

(के रूप में क्यों apply_along_axis धीमी है के लिए -। मैं नहीं जानता कि, शायद इसलिए कि समारोह शुद्ध पायथन में सरणी संस्करण की तुलना में इस प्रकार कम अनुकूलन अवसर लिखा और भी बहुत कुछ सामान्य है और)

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