सुन्न के साथ एक सरणी के कुशल थ्रॉल्डिंग फ़िल्टर


81

मुझे उन तत्वों को हटाने के लिए एक सरणी फ़िल्टर करने की आवश्यकता है जो एक निश्चित सीमा से कम हैं। मेरा वर्तमान कोड इस प्रकार है:

threshold = 5
a = numpy.array(range(10)) # testing data
b = numpy.array(filter(lambda x: x >= threshold, a))

समस्या यह है कि यह एक अस्थायी सूची बनाता है, जिसमें लैम्बडा फ़ंक्शन (धीमी) के साथ एक फिल्टर का उपयोग किया जाता है।

जैसा कि यह एक काफी सरल ऑपरेशन है, हो सकता है कि एक संख्यात्मक कार्य हो जो इसे एक कुशल तरीके से करता है, लेकिन मैं इसे खोजने में असमर्थ रहा हूं।

मैंने सोचा है कि इसे प्राप्त करने का एक और तरीका सरणी को छांटना हो सकता है, दहलीज के सूचकांक को ढूंढना और उस सूचकांक से एक टुकड़ा को बाद में वापस करना, लेकिन भले ही यह छोटे इनपुट के लिए तेज हो (और यह वैसे भी ध्यान देने योग्य नहीं होगा ), इसकी निश्चित रूप से asymptotically कम कुशल के रूप में इनपुट आकार बढ़ता है।

कोई विचार? धन्यवाद!

अद्यतन : मैंने कुछ माप भी लिए, और छँटाई + टुकड़ा करना तब भी शुद्ध अजगर फिल्टर की तुलना में दोगुना था जब इनपुट 100.000.000 प्रविष्टियाँ थी।

In [321]: r = numpy.random.uniform(0, 1, 100000000)

In [322]: %timeit test1(r) # filter
1 loops, best of 3: 21.3 s per loop

In [323]: %timeit test2(r) # sort and slice
1 loops, best of 3: 11.1 s per loop

In [324]: %timeit test3(r) # boolean indexing
1 loops, best of 3: 1.26 s per loop

2
हाँ, यह काफी अच्छा है :-) यह स्वचालित रूप से गणना भी करता है कि माप को औसत करने के लिए कितने पुनरावृत्तियों को निष्पादित करना चाहिए यदि कोड निष्पादित करने में बहुत कम समय लगता है
फोरट्रान

5
@yosukesabai - IPython में बिलियन मॉड्यूल का %timeitउपयोग किया गया है timeit। इस पर एक नज़र डालें, साथ ही साथ। docs.python.org/library/timeit.html
जो

जवाबों:


112

b = a[a>threshold] यह करना चाहिए

मैंने निम्नानुसार परीक्षण किया:

import numpy as np, datetime
# array of zeros and ones interleaved
lrg = np.arange(2).reshape((2,-1)).repeat(1000000,-1).flatten()

t0 = datetime.datetime.now()
flt = lrg[lrg==0]
print datetime.datetime.now() - t0

t0 = datetime.datetime.now()
flt = np.array(filter(lambda x:x==0, lrg))
print datetime.datetime.now() - t0

मुझे मिला

$ python test.py
0:00:00.028000
0:00:02.461000

http://docs.scipy.org/doc/numpy/user/basics.indexing.html#boolean-or-mask-index-arrays


1
जोड़ा गया परीक्षा परिणाम, न कि मुझे लगता है कि इसे क्या करना चाहिए। : p
yosukesabai

3
इस तरह की अनुक्रमणिका सरणी के आकार को बनाए नहीं रखती है, यह कैसे संभव है कि तत्वों की समान संख्या और सबथ्रेशोल्ड मानों को शून्य करना संभव है?
लिनेलो

9
@linello, [[ए <= थ्रेशोल्ड] = ० उस हिस्से से बाहर निकलने वाला है जो थ्रेशोल्ड से अधिक नहीं है
yosukesabai

4
मैं दो मानदंडों के आधार पर फ़िल्टरिंग के मुद्दे में भाग गया। यहाँ समाधान है: stackoverflow.com/a/3248599/1373468
रॉबिन न्यूहाउस

@yosukesabai क्या वास्तव में मूल मूल्यों को बदलने के बिना, वास्तव में ऐसा करना संभव है। अगर np.maऐसा करने का मतलब है, तो मैं यह पता नहीं लगा सकता कि कैसे।
एमबर्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.