कभी-कभी आपको गैर-मुहावरेदार संख्याओं को लिखने की आवश्यकता होती है, यदि आप वास्तव में अपनी गणना को गति देना चाहते हैं जो आप देशी अंकों के साथ नहीं कर सकते हैं।
numba
अपने अजगर कोड को निम्न-स्तरीय सी के लिए संकलित करता है क्योंकि बहुत सारे खाँसी आमतौर पर सी के रूप में तेजी से होती है, यह ज्यादातर तब उपयोगी होता है जब आपकी समस्या स्वयं खतना के साथ देशी वैश्वीकरण को उधार नहीं देती है। यह एक उदाहरण है (जहां मैंने माना कि सूचकांक सन्निहित और क्रमबद्ध हैं, जो उदाहरण डेटा में भी परिलक्षित होता है):
import numpy as np
import numba
# use the inflated example of roganjosh https://stackoverflow.com/a/58788534
data = [1.00, 1.05, 1.30, 1.20, 1.06, 1.54, 1.33, 1.87, 1.67]
index = [0, 0, 1, 1, 1, 1, 2, 3, 3]
data = np.array(data * 500) # using arrays is important for numba!
index = np.sort(np.random.randint(0, 30, 4500))
# jit-decorate; original is available as .py_func attribute
@numba.njit('f8[:](f8[:], i8[:])') # explicit signature implies ahead-of-time compile
def diffmedian_jit(data, index):
res = np.empty_like(data)
i_start = 0
for i in range(1, index.size):
if index[i] == index[i_start]:
continue
# here: i is the first _next_ index
inds = slice(i_start, i) # i_start:i slice
res[inds] = data[inds] - np.median(data[inds])
i_start = i
# also fix last label
res[i_start:] = data[i_start:] - np.median(data[i_start:])
return res
और यहाँ कुछ समय IPython के %timeit
जादू का उपयोग कर रहे हैं :
>>> %timeit diffmedian_jit.py_func(data, index) # non-jitted function
... %timeit diffmedian_jit(data, index) # jitted function
...
4.27 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
65.2 µs ± 1.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
इन नंबरों में अपडेटेड उदाहरण डेटा का उपयोग करना (जैसे कि पायथन फ़ंक्शन का रनटाइम बनाम JIT- त्वरित फंक्शनलियो का रनटाइम) हैं
>>> %timeit diffmedian_jit.py_func(data, groups)
... %timeit diffmedian_jit(data, groups)
2.45 s ± 34.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
93.6 ms ± 518 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
यह छोटे केस में 65x स्पीडअप और बड़े केस में 26x स्पीडअप (तुलना में धीमी गति कोड की तुलना में) त्वरित कोड का उपयोग करता है। एक और उल्टा यह है कि (सामान्य संख्या के साथ विशिष्ट वैश्वीकरण के विपरीत) हमें इस गति को प्राप्त करने के लिए अतिरिक्त मेमोरी की आवश्यकता नहीं थी, यह सभी अनुकूलित और संकलित निम्न-स्तरीय कोड के बारे में है जो कि समाप्त हो रहा है।
उपरोक्त फ़ंक्शन मानता है कि सुन्न int arrays हैं int64
डिफ़ॉल्ट रूप से , जो वास्तव में विंडोज पर मामला नहीं है। तो एक विकल्प कॉल से हस्ताक्षर को हटाने के लिए हैnumba.njit
, उचित जस्ट-इन-टाइम संकलन को ट्रिगर किया जाए। लेकिन इसका मतलब यह है कि फ़ंक्शन को पहले निष्पादन के दौरान संकलित किया जाएगा, जो समय परिणामों के साथ मध्यस्थता कर सकता है (हम या तो मैन्युअल रूप से फ़ंक्शन को निष्पादित कर सकते हैं, प्रतिनिधि डेटा प्रकारों का उपयोग कर सकते हैं, या बस स्वीकार कर सकते हैं कि पहली बार निष्पादन बहुत धीमा होगा, जिसे करना चाहिए अनदेखा किया जाए)। यह वही है जो मैंने एक हस्ताक्षर को निर्दिष्ट करके रोकने की कोशिश की थी, जो समय-समय पर संकलन से आगे बढ़ता है।
वैसे भी, ठीक से JIT मामले में डेकोरेटर की हमें जरूरत है
@numba.njit
def diffmedian_jit(...):
ध्यान दें कि उपर्युक्त समय मैंने जो जीट-संकलित फ़ंक्शन के लिए दिखाया था, केवल एक बार फ़ंक्शन संकलित होने के बाद लागू होता है। यह या तो परिभाषा पर होता है (उत्सुक संकलन के साथ, जब एक स्पष्ट हस्ताक्षर पारित हो जाता है numba.njit
), या पहले फ़ंक्शन कॉल के दौरान (आलसी संकलन के साथ, जब कोई हस्ताक्षर पारित नहीं होता हैnumba.njit
)। यदि फ़ंक्शन केवल एक बार निष्पादित होने जा रहा है, तो इस विधि की गति के लिए संकलन समय पर भी विचार किया जाना चाहिए। यह आम तौर पर केवल संकलित कार्यों के लायक है यदि संकलन + निष्पादन का कुल समय अप्रयुक्त रनटाइम से कम है (जो वास्तव में उपरोक्त मामले में सच है, जहां देशी पायथन फ़ंक्शन बहुत धीमा है)। यह ज्यादातर तब होता है जब आप अपने संकलित फ़ंक्शन को बहुत बार कॉल कर रहे होते हैं।
के रूप में max9111 एक टिप्पणी में बताया गया है, में से एक महत्वपूर्ण विशेषता numba
है cache
कीवर्ड के लिए jit
। पासिंग cache=True
के लिए numba.jit
, डिस्क के लिए संकलित समारोह का संग्रह किया जायेगा ताकि दिया अजगर मॉड्यूल के अगले निष्पादन के दौरान समारोह से वहाँ के बजाय कंपाइल है, जो फिर से छोड़ कर सकते हैं लंबे समय के रनटाइम लोड किया जाएगा।
scipy.ndimage.median
लिंक किए गए उत्तर में सुझाव दिया था? यह मुझे नहीं लगता है कि इसे प्रति लेबल समान संख्या में तत्वों की आवश्यकता है। या किसी को याद किया था?