2012-06-18 15 views
7

साथ मतलब मैं शुद्ध अजगर में औसत गति की गणना के एल्गोरिथ्म है:Numpy हालत

speed = [...] 
    avg_speed = 0.0 
    speed_count = 0 
    for i in speed: 
     if i > 0: # I dont need zeros 
      avg_speed += i 
      speed_count += 1 

    if speed_count == 0: 
     return 0.0 

    return avg_speed/speed_count 

वहाँ Numpy के साथ इस कार्यों के पुनर्लेखन के लिए कोई तरीका है?

उत्तर

9
import numpy as np 

def avg_positive_speed(speed): 
    s = np.array(speed) 
    positives = s > 0 
    if positives.any(): 
     return s[positives].mean() 
    else: 
     return 0. 


speed = [1., 2., 0., 3.] 
print avg_positive_speed(speed) 
# prints 2.0 

print avg_positive_speed([0., 0.]) 
# prints 0.0 
3

मैं तुम्हें एक numpy समाधान चाहते हैं पता है, तो यह है कि मापदंड (@ eumiro के पहले पोस्ट निश्चित रूप से करता है) को पूरा नहीं करता, लेकिन सिर्फ एक विकल्प के रूप में, यहाँ एक अनुकूलित अजगर संस्करण है जो आश्चर्यजनक रूप से (मेरे लिए कम से कम है) काफी तेज़ हो गया!

speeds = [i for i in speed if i > 0] 
return sum(speeds)/(1.0 * len(speeds)) if sum(speeds) > 0 else 0.0 

numpy (या मूल) गति के मामले में कार्यान्वयन के साथ इस तुलना करने के लिए दिलचस्प हो सकता है।

In [14]: timeit original(speed)    # original code 
1000 loops, best of 3: 1.13 ms per loop 

In [15]: timeit python_opt(speed)   # above Python 2 liner 
1000 loops, best of 3: 582 us per loop 

In [16]: timeit avg_positive_speed(speed) # numpy code 
1000 loops, best of 3: 1.2 ms per loop 

जहां

speed = range(10000) 

मैं सोचा होगा कि numpy बढ़त यहाँ होता .. किसी को पता क्यों यह ट्रेल्स?

अद्यतन:

speed = range(100000) साथ:

In [19]: timeit original(speed) 
100 loops, best of 3: 12.2 ms per loop 

In [20]: timeit python_opt(speed) 
100 loops, best of 3: 11 ms per loop 

In [21]: timeit avg_positive_speed(speed) 
100 loops, best of 3: 12.5 ms per loop 

अभी भी यकीन नहीं है कि numpyइस विशेष समस्या के लिए एक अच्छा उपकरण है, जब तक कि वहाँ गति की एक विशाल संख्या में हैं :)

numpy मेमोरी मेमोरी कैसे करता है? सूची की समझ कुछ बिंदुओं पर कुछ बिंदुओं पर टक्कर लगी होगी।

+0

बड़ी संख्या में आज़माएं। 1000 के साथ, एक सूची से एक सरणी में रूपांतरण समय पर हावी है। –

+0

@ जोकिंगटन अभी यह कर रहा है .. :) – Levon

+2

ध्यान रखें कि एक बड़ी सूची में एक numpy सरणी में रूपांतरण अपेक्षाकृत धीमी प्रक्रिया है। यदि डेटा पहले से ही एक numpy सरणी है (जो एक सूची से _far_ कम स्मृति का उपयोग करता है) तो numpy संस्करण बहुत तेज हो जाएगा। अन्यथा, आपको एक ही ऑपरेशन के लिए एक बड़ा अंतर दिखाई नहीं देगा, क्योंकि अधिकांश समय सूची को सरणी में परिवर्तित करने के लिए खाया जाएगा। –

16

समारोह numpy.average एक weights तर्क है, जहां आप कुछ हालत सरणी खुद के लिए लागू से उत्पन्न एक बूलियन सरणी डाल सकते हैं प्राप्त कर सकते हैं - इस मामले में, एक तत्व जा रहा है 0 से अधिक:

average_speed = numpy.average(speeds, weights=(speeds > 0)) 

इस आशा मदद करता है

+4

+1, यह 'वजन' संकेत अद्भुत है! – eumiro

+0

यह समाधान बहुत अच्छा है, धन्यवाद। –

9

मैं कोई भी सुझाव दिया है हैरान हूँ कम से कम समाधान:

speeds_np = np.array(speeds) 

speeds_np[speeds_np>0].mean() 

स्पष्टीकरण:

speedsNp > 0 समानता (इन) समानता को संतुष्ट करने वाले आकार के एक बुलियन सरणी बनाता है। यदि speedsNp में खिलाया जाता है, तो यह केवल speedNp के संबंधित मान उत्पन्न करता है जहां बूलियन सरणी का मान True है। आपको बस इतना करना है, परिणाम के mean() लें।

+1

यह निश्चित रूप से यहां सबसे अच्छा जवाब है। धन्यवाद @ टिम – mjp