计算生成器的python中的平均值

nic*_*ell 13 python generator mean

我正在做一些统计工作,我有一个(大)随机数集合来计算平均值,我想使用生成器,因为我只需要计算均值,所以我不需要存储数字.

问题是numpy.mean如果你把它传给发电机就会中断.我可以写一个简单的函数来做我想要的,但我想知道是否有一个正确的,内置的方法来做到这一点?

如果我能说"sum(values)/ len(values)"会很好,但是len不适用于genetators,并且总和已经消耗的值.

这是一个例子:

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)
Run Code Online (Sandbox Code Playgroud)

这两个都给出相同,正确,答案,买my_mean不适用于列表,numpy.mean不适用于生成器.

我真的很喜欢使用发电机的想法,但这样的细节似乎破坏了事情.

Eri*_*rik 19

一般来说,如果你正在进行浮点数的流式均值计算,那么你最好使用一个数值更稳定的算法而不是简单地求和发生器并除以长度.

其中最简单的(我知道)通常记入Knuth,并计算方差.该链接包含一个python实现,但只是为了完整性而复制了平均部分.

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
Run Code Online (Sandbox Code Playgroud)

我知道这个问题已经超级老了,但它仍然是谷歌的第一个热门,所以发帖似乎很合适.我仍然很遗憾python标准库不包含这段简单的代码.


Mar*_*som 7

只需对代码进行一次简单的更改就可以使用它们.生成器旨在可互换地用于for循环中的列表.

def my_mean(values):
    n = 0
    Sum = 0.0
    for v in values:
        Sum += v
        n += 1
    return Sum / n
Run Code Online (Sandbox Code Playgroud)

  • Sum中的大写字母通常保留给类. (4认同)
  • 和`sum`是内置的,所以你应该使用`sum_`或`total` (4认同)
  • @xApple,我试图使其与问题中的代码类似;你会看到该变量也被命名为“Sum”。就我个人而言,我会遵循 PEP 8 中的约定。 (2认同)

jfs*_*jfs 5

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)
Run Code Online (Sandbox Code Playgroud)

statistics.mean()在Python 3.4,但它要求list()输入:

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
Run Code Online (Sandbox Code Playgroud)

其中_sum()返回准确的总和(math.fsum()样函数,除了float还支持Fraction,Decimal).