दिलचस्प पोस्ट
सीएसएस के साथ स्वचालित रूप से पाठ के 2 कॉलम प्रवाह करें अजगर में ईमेल प्राप्त करें और भेजें Android अंतहीन सूची कैसे वेब अनुप्रयोग में गुण फ़ाइल को पढ़ने के लिए? किसी वेब ऐप से मूल आईओएस एप कैसे खोल सकता है कैसे एसेट फ़ोल्डर पर एक फ़ाइल के लिए एंड्रॉइड पथ स्ट्रिंग प्राप्त करने के लिए? MySQL: ग्रुप बाय में नहीं है IDisposable को सही ढंग से कार्यान्वित करना जावा में हैश कोड () स्ट्रिंग में एक गुणक के रूप में 31 का उपयोग क्यों करता है? फ्लेक्सबॉक्स में समान ऊंचाई कॉलम को अक्षम कैसे करें? सूची समझ में दोहरा परिवर्तन वॉली – JSONArrayRequest का उपयोग करके एक पोस्ट अनुरोध भेजा जा रहा है IOS7 में एक पारदर्शी UIToolbar या UINavigationBar कैसे आकर्षित करें मैं अपने ऐप में स्क्रीन कैसे रखूं? ऑरेकल में सभी टेबल बाधाओं को अक्षम करें

नुम्पी: मूल्य का पहला सूचकांक तेजी से ढूंढें

मैं नंबरी सरणी में किसी संख्या की पहली घटना का सूचक कैसे पा सकता हूं? स्पीड मेरे लिए महत्वपूर्ण है मुझे निम्नलिखित उत्तरों में कोई दिलचस्पी नहीं है क्योंकि वे पूरी सरणी को स्कैन करते हैं और जब वे पहली घटना को मिलते हैं तब रोकते नहीं हैं:

itemindex = numpy.where(array==item)[0][0] nonzero(array == item)[0][0] 

नोट 1: उस प्रश्न से जवाब में से कोई भी प्रासंगिक नहीं लगता है क्या किसी सरणी में कुछ के पहले सूचकांक को वापस करने के लिए एक नफ काम है?

नोट 2: सी-संकलित विधि का उपयोग करना पायथन लूप के लिए प्राथमिकता है।

वेब के समाधान से एकत्रित समाधान "नुम्पी: मूल्य का पहला सूचकांक तेजी से ढूंढें"

इसमें नॉर्मल 2.0.0 के लिए निर्धारित सुविधा है: https://github.com/numpy/numpy/issues/2269

यद्यपि यह आपके लिए बहुत देर हो चुकी है, लेकिन भविष्य के संदर्भ के लिए: numba का उपयोग करना ( 1 ) सबसे आसान तरीका है, जब तक कि यह शून्य न हो जाए। यदि आप एनाकोंडा अजगर वितरण का उपयोग करते हैं तो यह पहले से ही स्थापित होना चाहिए। कोड संकलित किया जाएगा ताकि यह तेज़ी से हो सके।

 @jit(nopython=True) def find_first(item, vec): """return the index of the first occurence of item in vec""" for i in xrange(len(vec)): if item == vec[i]: return i return -1 

और फिर:

 >>> a = array([1,7,8,32]) >>> find_first(8,a) 2 

आप एक बूलीयन सरणी को एक अजगर स्ट्रिंग में array.tostring() का उपयोग करके कनवर्ट कर सकते हैं और फिर () विधि का उपयोग कर सकते हैं:

 (array==item).tostring().find('\x01') 

इसमें डेटा की प्रतिलिपि करना शामिल है, हालांकि, क्योंकि अजगर स्ट्रिंग को अपरिवर्तनीय होने की आवश्यकता है। एक फायदा यह है कि आप \x00\x01 ढूँढ़ने के लिए बढ़ते बढ़ते उदाहरण भी खोज सकते हैं

मैंने कई तरीकों के लिए एक बेंचमार्क बनाया है:

  • argwhere
  • सवाल के रूप में nonzero
  • । रॉब रीलिंक के जवाब में
  • अजगर लूप
  • फोरट्रान लूप

पायथन और फोरट्रान कोड उपलब्ध हैं। मैंने उन लोगों को छोड़ दिया जिन्हें एक सूची में परिवर्तित करना था।

लॉग पैमाने पर परिणाम एक्स-एक्स सुई की स्थिति है (यह पता लगाने में अधिक समय लगता है कि क्या यह सरणी के नीचे है); अंतिम मान एक सुई है जो सरणी में नहीं है। वाई-अक्ष का पता लगाने का समय है

बेंचमार्क परिणाम

सरणी में 1 लाख तत्व थे और टेस्ट 100 बार चलाए गए थे। परिणाम अभी भी थोड़ा उतार-चढ़ाव करते हैं, लेकिन गुणात्मक प्रवृत्ति स्पष्ट है: पायथन और एफ 2 एसपी ने पहले तत्व पर छोड़ दिया ताकि वे अलग-अलग पैमाने पर हो सकें। यदि सुई पहले 1% में नहीं है, तो पायथन बहुत धीमा हो जाता है, जबकि f2py तेज है (लेकिन आपको उसे संकलित करने की आवश्यकता है)।

संक्षेप करने के लिए, f2py सबसे तेज़ समाधान है , खासकर यदि सुई काफी जल्दी दिखाई देती है

यह नहीं बनाया गया है जिसमें कष्टप्रद है, लेकिन यह वास्तव में केवल 2 मिनट का काम है खोज फ़ाइल नामक फ़ाइल में इसे जोड़ें। search.f90 :

 subroutine find_first(needle, haystack, haystack_length, index) implicit none integer, intent(in) :: needle integer, intent(in) :: haystack_length integer, intent(in), dimension(haystack_length) :: haystack !f2py intent(inplace) haystack integer, intent(out) :: index integer :: k index = -1 do k = 1, haystack_length if (haystack(k)==needle) then index = k - 1 exit endif enddo end 

यदि आप integer अलावा किसी अन्य चीज़ की तलाश कर रहे हैं, तो बस टाइप बदल दें। फिर का उपयोग करके संकलित करें:

 f2py -c -m search search.f90 

जिसके बाद आप कर सकते हैं (पायथन से):

 import search print(search.find_first.__doc__) a = search.find_first(your_int_needle, your_int_array) 

मुझे लगता है कि आपने एक ऐसी समस्या का सामना किया है, जहां एक अलग विधि और कुछ प्राथमिकताओं के जरिए पता चला कि वास्तव में मदद मिलेगी। जिस चीज की आपके पास डेटा के पहले वाई प्रतिशत में अपना जवाब खोजने की एक एक्स संभावना है भाग्यशाली होने की आशा के साथ समस्या को विभाजित करते हुए यह नेस्टेड सूची समझ या कुछ के साथ अजगर में कर रहा है

सीटीपीपी का उपयोग करते हुए यह सीक्रेट फ़ंक्शन को लिखना बहुत कठिन नहीं है।

सी कोड मैं एक साथ hacked (index.c):

 long index(long val, long *data, long length){ long ans, i; for(i=0;i<length;i++){ if (data[i] == val) return(i); } return(-999); } 

और अजगर:

 # to compile (mac) # gcc -shared index.c -o index.dylib import ctypes lib = ctypes.CDLL('index.dylib') lib.index.restype = ctypes.c_long lib.index.argtypes = (ctypes.c_long, ctypes.POINTER(ctypes.c_long), ctypes.c_long) import numpy as np np.random.seed(8675309) a = np.random.random_integers(0, 100, 10000) print lib.index(57, a.ctypes.data_as(ctypes.POINTER(ctypes.c_long)), len(a)) 

और मुझे 9 2 मिलता है

अजगर को एक उचित समारोह में लपेटें और वहां आप जाएं

इस सी के लिए सी संस्करण बहुत अधिक (~ 20x) तेज है (चेतावनी, मैं समय के साथ अच्छा नहीं हूँ)

 import timeit t = timeit.Timer('np.where(a==57)[0][0]', 'import numpy as np; np.random.seed(1); a = np.random.random_integers(0, 1000000, 10000000)') t.timeit(100)/100 # 0.09761879920959472 t2 = timeit.Timer('lib.index(57, a.ctypes.data_as(ctypes.POINTER(ctypes.c_long)), len(a))', 'import numpy as np; np.random.seed(1); a = np.random.random_integers(0, 1000000, 10000000); import ctypes; lib = ctypes.CDLL("index.dylib"); lib.index.restype = ctypes.c_long; lib.index.argtypes = (ctypes.c_long, ctypes.POINTER(ctypes.c_long), ctypes.c_long) ') t2.timeit(100)/100 # 0.005288000106811523 

क्रमबद्ध सरणियों के मामले में np.searchsorted

यदि आपकी सूची को हल किया जाता है , तो आप 'बिस्केक्ट' पैकेज के साथ सूचकांक की त्वरित खोज प्राप्त कर सकते हैं। हे (ओ) के बजाय ओ (लॉग (एन)) है

 bisect.bisect(a, x) 

सरणी में एक्स ढूँढता है, निश्चित रूप से क्रमबद्ध मामले में किसी भी सी-रूटिन से पहले सभी तत्वों (लंबी सूची के लिए) के माध्यम से जा रहा है।

कभी-कभी पता होना अच्छा है

जहां तक ​​मुझे पता है कि केवल एनपी.एनी और एनपी.ऑल बूलीयन एरे पर है, वह कम-सर्किट है।

आपके मामले में, एमएमपी को पूरे सरणी से दो बार जाना पड़ता है, एक बार बुलियन की स्थिति बनाने के लिए और दूसरी बार सूचकांक ढूंढने के लिए।

इस मामले में मेरी सिफारिश cython का उपयोग करने के लिए होगी मुझे लगता है कि इस मामले के लिए एक उदाहरण को समायोजित करना आसान होना चाहिए, खासकर यदि आपको अलग-अलग डीटीपों और आकारों के लिए बहुत लचीलेपन की आवश्यकता नहीं है

मुझे अपनी नौकरी के लिए इसकी ज़रूरत है इसलिए मैंने खुद को पायथन और नंपी सी इंटरफ़ेस सिखाया और अपना खुद लिखा। http://pastebin.com/GtcXuLyd यह केवल 1-डी सरणियों के लिए है, लेकिन अधिकांश डेटा प्रकार (इंट, फ्लोट, या स्ट्रिंग) के लिए काम करता है और परीक्षण से पता चला है कि यह शुद्ध पायथन- numpy।

@tal पहले सूचकांक को खोजने के लिए पहले से ही एक numba फ़ंक्शन प्रस्तुत किया था लेकिन यह केवल 1D सरणियों के लिए काम करता है। np.ndenumerate साथ आप एक arbitarly आयामी सरणी में पहले सूचकांक पा सकते हैं:

 from numba import njit import numpy as np @njit def index(array, item): for idx, val in np.ndenumerate(array): if val == item: return idx return None 

नमूना मामला:

 >>> arr = np.arange(9).reshape(3,3) >>> index(arr, 3) (1, 0) 

समय बताता है कि यह प्रदर्शन के समान होता है जो कि समाधान के लिए होता है:

 arr = np.arange(100000) %timeit index(arr, 5) # 1000000 loops, best of 3: 1.88 µs per loop %timeit find_first(5, arr) # 1000000 loops, best of 3: 1.7 µs per loop %timeit index(arr, 99999) # 10000 loops, best of 3: 118 µs per loop %timeit find_first(99999, arr) # 10000 loops, best of 3: 96 µs per loop 

आप डैटा एट्रिब्यूट का उपयोग करते हुए एक numpy array पर रीड-राइट बफर प्राप्त कर सकते हैं। उस पर बदलना, लेकिन आपको यह जानना होगा कि क्या आपका डेटा पंक्ति या स्तंभ प्रमुख है (फ्लैट सूचक को सूचकांक ट्यूपल में परिवर्तित करने के लिए ndarray.shape और numpy.unravel_index का उपयोग करें)।

बस एक नोट है कि यदि आप खोजों का अनुक्रम कर रहे हैं, तो स्ट्रिंग में परिवर्तित करने की तरह कुछ चालाक से प्रदर्शन लाभ, बाहरी लूप में खो सकता है यदि खोज आयाम काफी बड़ा नहीं है देखें कि कैसे वेटरेटिंग खोज 1 का प्रदर्शन ऊपर दिखाए गए स्ट्रिंग ट्रांजैक्शन ट्रिक का इस्तेमाल करता है और जो कि 2 के भीतर एआरएमएक्स का उपयोग करता है (साथ-साथ नॉन-मैच रिटर्न सुनिश्चित करने के लिए एक समायोजन)

 import numpy,time def find1(arr,value): return (arr==value).tostring().find('\x01') def find2(arr,value): #find value over inner most axis, and return array of indices to the match b = arr==value return b.argmax(axis=-1) - ~(b.any()) for size in [(1,100000000),(10000,10000),(1000000,100),(10000000,10)]: print(size) values = numpy.random.choice([0,0,0,0,0,0,0,1],size=size) v = values>0 t=time.time() numpy.apply_along_axis(find1,-1,v,1) print('find1',time.time()-t) t=time.time() find2(v,1) print('find2',time.time()-t) 

आउटपुट

 (1, 100000000) ('find1', 0.25300002098083496) ('find2', 0.2780001163482666) (10000, 10000) ('find1', 0.46200013160705566) ('find2', 0.27300000190734863) (1000000, 100) ('find1', 20.98099994659424) ('find2', 0.3040001392364502) (10000000, 10) ('find1', 206.7590000629425) ('find2', 0.4830000400543213) 

उसमें कहा गया है, सी में लिखी गई एक खोज इन तरीकों से कम से कम एकदम कम होगी

आप अपने सरणी को एक list में गुप्त कर सकते हैं और इसका index() विधि का उपयोग कर सकते हैं:

 i = list(array).index(item) 

जहाँ तक मुझे पता है, यह सी संकलित विधि है।

इस बारे में कैसा है

 import numpy as np np.amin(np.where(array==item))