2011-02-10 14 views
13

के लिए पायथन में गणना का मतलब है मैं कुछ आंकड़े काम कर रहा हूं, मेरे पास गणना करने के लिए यादृच्छिक संख्याओं का एक (बड़ा) संग्रह है, मैं जेनरेटर के साथ काम करना चाहता हूं, क्योंकि मुझे बस गणना करने की आवश्यकता है मतलब है, इसलिए मुझे संख्याओं को स्टोर करने की आवश्यकता नहीं है।जेनरेटर

समस्या यह है कि numpy.mean तोड़ता है यदि आप इसे जनरेटर पास करते हैं। मैं जो चाहता हूं उसे करने के लिए मैं एक साधारण कार्य लिख सकता हूं, लेकिन मुझे आश्चर्य है कि ऐसा करने के लिए एक उचित, अंतर्निहित तरीका है या नहीं?

यह अच्छा होगा अगर मैं "योग (मान)/लेन (मान)" कह सकता हूं, लेकिन लेन जेनेटर्स के लिए काम नहीं करता है, और पहले ही उपभोग मूल्यों का योग करता है।

import numpy 

def my_mean(values): 
    n = 0 
    Sum = 0.0 
    try: 
     while True: 
      Sum += next(values) 
      n += 1 
    except StopIteration: pass 
    return float(Sum)/n 

X = [k for k in range(1,7)] 
Y = (k for k in range(1,7)) 

print numpy.mean(X) 
print my_mean(Y) 

इन दोनों, एक ही है, सही है, जवाब दे खरीदने my_mean सूचियों के लिए काम नहीं करता है, और numpy.mean जनरेटर के लिए काम नहीं करता:

यहाँ एक उदाहरण है।

मुझे जेनरेटर के साथ काम करने का विचार पसंद है, लेकिन इस तरह के विवरण चीजों को खराब करना प्रतीत होता है।

+2

तुम्हें पता था कि कितने यादृच्छिक संख्या जनरेटर अपने उत्पादन होता है, आप नहीं है? –

+0

@ सेवन मार्नच: मान लीजिए जनरेटर फ़ाइल से पढ़ रहा है? – Jimmy

+1

यदि आप वास्तव में डेटा को स्टोर नहीं करना चाहते हैं (और अपने धीमे 'योग 'फ़ंक्शन को लागू नहीं करते हैं) तो आप एक गिनती जनरेटर बना सकते हैं और इसे इस तरह कहते हैं:' co = countingGen(); माध्य = योग (सह (डेटा))/co.getCount() ' –

उत्तर

5

आपके कोड में बस एक साधारण परिवर्तन आपको दोनों का उपयोग करने देगा। जेनरेटर का इस्तेमाल फॉर-लूप में सूचियों के लिए एक दूसरे के लिए किया जा सकता था।

def my_mean(values): 
    n = 0 
    Sum = 0.0 
    for v in values: 
     Sum += v 
     n += 1 
    return Sum/n 
+2

Sum में पूंजी पत्र आमतौर पर कक्षाओं के लिए आरक्षित होते हैं। – xApple

+0

@xApple, मैंने इसे प्रश्न में कोड के समान बनाने की कोशिश की; आप देखेंगे कि चर को 'Sum' नाम दिया गया है। व्यक्तिगत रूप से मैं पीईपी 8. –

+2

में सम्मेलन का पालन करता और 'sum' एक अंतर्निर्मित है, इसलिए आपको' sum_' या 'कुल' –

-1

प्रयास करें:

import itertools 

def mean(i): 
    (i1, i2) = itertools.tee(i, 2) 
    return sum(i1)/sum(1 for _ in i2) 

print mean([1,2,3,4,5]) 

tee, किसी भी iterable i (उदाहरण, एक जनरेटर, एक सूची, आदि) के लिए अपने इटरेटर नकल आपको संक्षेप और गिनती के लिए अन्य के लिए एक डुप्लिकेट उपयोग करने की अनुमति होगी।

(ध्यान दें कि 'टीई' अभी भी मध्यवर्ती भंडारण का उपयोग करेगा)।

+2

यह अस्थायी रूप से पूरी सूची संग्रहीत करता है। मेमोरी-वार, यह पहले सूची में कनवर्ट करने के बराबर है और 'sum (a)/len (a) 'का उपयोग कर रहा है, लेकिन एक सूची का उपयोग करना तेज़ होगा। –

+0

अच्छा बिंदु, सच - मैं बस देख रहा था कि टीई() लागू किया गया है। जब ऐसा होता है तो मुझे नफ़रत होती है। :-) – payne

+0

आपको लगता है कि 'टीई' को केवल क्लोन इटरेटर्स के बीच "diff" संग्रहित करके कार्यान्वित किया जा सकता है, यानी तत्वों का उपभोग करने वाले तत्वों के अलावा, लेकिन दूसरा अभी तक नहीं है। –

1

एक तरह से

numpy.fromiter(Y, int).mean() 

होगा, लेकिन यह वास्तव में अस्थायी रूप से संख्या संग्रहीत करता है।

0
def my_mean(values): 
    n = 0 
    sum = 0 
    for v in values: 
     sum += v 
     n += 1 
    return sum/n 

ऊपर अगर आप किसी सूची या पुनरावर्तक मिल आप कोई फर्क नहीं पड़ता अच्छे हैं for का उपयोग कर values पुनरावृति करने के अलावा, बहुत अपने कोड के समान है। पायथन sum विधि हालांकि बहुत अनुकूलित है, इसलिए जब तक कि सूची वास्तव में वास्तव में लंबी नहीं है, तो आप डेटा को अस्थायी रूप से संग्रहीत करने में अधिक खुश रह सकते हैं।

(यह भी ध्यान दें कि जब से तुम python3 उपयोग कर रहे हैं, आप की जरूरत नहीं है float(sum)/n)

+1

'sum = 0' करके आप बिल्टिन फ़ंक्शन मास्किंग कर रहे हैं। – xApple

1

आपका दृष्टिकोण एक अच्छा है, लेकिन आप के बजाय बार-बार कॉल next के बजाय for x in y मुहावरा इस्तेमाल करना चाहिए जब तक आप एक StopIteration मिल । यह सूचियों और जेनरेटर दोनों के लिए काम करता है:

def my_mean(values): 
    n = 0 
    Sum = 0.0 

    for value in values: 
     Sum += value 
     n += 1 
    return float(Sum)/n 
+0

पूंजी अक्षरों जैसे 'Sum' में आमतौर पर कक्षाओं के लिए आरक्षित होते हैं। – xApple

3

पुराने तरीके से यह करने के लिए:

def mean(data): 
    if iter(data) is data: 
     data = list(data) 
    n = len(data) 
    if n < 1: 
     raise StatisticsError('mean requires at least one data point') 
    return _sum(data)/n 

जहां _sum() एक सटीक योग देता है (math.fsum() की तरह समारोह:

def my_mean(values): 
    sum, n = 0, 0 
    for x in values: 
     sum += x 
     n += 1 
    return float(sum)/n 
4
def my_mean(values): 
    total = 0 
    for n, v in enumerate(values, 1): 
     total += v 
    return total/n 

print my_mean(X) 
print my_mean(Y) 

statistics.mean() in Python 3.4 लेकिन it calls list() on the input नहीं है कि float के अलावा भी समर्थन करते हैं एस Fraction, Decimal)।

+0

प्लस वन 'एन्युमरेट' के लिए उपयोग करना चाहिए - यह सबसे अधिक पाइथोनिक तरीका है, आईएमओ। – Tgsmith61591

0

आप पहले से जनरेटर की लंबाई को जानते हैं और आप स्मृति में पूरी सूची के भंडारण से बचना चाहते हैं, तो आप उपयोग कर सकते हैं:

reduce(np.add, generator)/length 
14

सामान्य तौर पर आप एक स्ट्रीमिंग कर रहे हैं अस्थायी की गणना मतलब बिंदु संख्या, आप जेनरेटर को संक्षेप में और लंबाई से विभाजित करने की तुलना में अधिक संख्यात्मक स्थिर एल्गोरिदम का उपयोग करके शायद बेहतर हो सकते हैं।

इनमें से सबसे सरल (जो मुझे पता है) आमतौर पर credited to Knuth है, और भिन्नता की गणना भी करता है। लिंक में एक पायथन कार्यान्वयन होता है, लेकिन केवल पूर्ण भाग को पूर्णता के लिए यहां कॉपी किया गया है।

def mean(data): 
    n = 0 
    mean = 0.0 

    for x in data: 
     n += 1 
     mean += (x - mean)/n 

    if n < 1: 
     return float('nan'); 
    else: 
     return mean 

मैं जानता हूँ कि इस सवाल का सुपर पुराना है, लेकिन यह अभी भी गूगल पर पहली हिट है, तो यह पोस्ट करने के लिए उचित लग रहा था। मुझे अभी भी दुःख है कि पायथन मानक पुस्तकालय में कोड का यह सरल टुकड़ा नहीं है।

0

आप सरणी के आकार को कम जानने के बिना उपयोग कर सकते हैं:

from itertools import izip, count 
reduce(lambda c,i: (c*(i[1]-1) + float(i[0]))/i[1], izip(values,count(1)),0) 
संबंधित मुद्दे