用一次迭代计算均值和方差

15 投票
8 回答
24617 浏览
提问于 2025-04-15 19:46

我有一个数字的迭代器,比如一个文件对象:

f = open("datafile.dat")

现在我想计算:

mean = get_mean(f)
sigma = get_sigma(f, mean)

什么是最好的实现方式?假设这个文件很大,我希望避免读取两次。

8 个回答

3

从可迭代对象中创建一个列表,或者使用 itertools.tee()

5

我觉得Nick D的回答是对的。

假设你想在一次读取文件的过程中同时计算平均值和方差(而不是两个函数一个接一个地调用),你可以先把所有数值的总和和它们的平方和都算出来,然后用这些总和(再加上读取的元素数量)来同时计算平均值和方差。

这里面有一些数值稳定性的问题,但在

http://en.wikipedia.org/wiki/Computational_formula_for_the_variance

这个链接里,你可以找到你需要的基本思路。更多的细节可以在

http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance

找到,我建议你看看“简单算法”那一部分。

希望这对你有帮助,

Massimo

11

如果你想只循环一次,可以这样写你的求和函数:

def mysum(l):
    s2 = 0
    s = 0
    for e in l:
        s += e
        s2 += e * e
    return (s, s2)

然后在你的 sigma 函数中使用这个结果。

编辑: 现在你可以这样计算方差:(s2 - (s*s) / N) / N

根据 @Adam Bowen 的评论,
请记住,如果我们使用数学上的一些 技巧 来变换原来的公式,
可能会影响结果的准确性。

撰写回答