我可以计算这些数字的平均值吗?

7

我想知道如果我有这些数字,是否可以计算它们的平均值:

int currentCount = 12;
float currentScore = 6.1123   (this is a range of 1 <-> 10).

现在,如果我收到另一个分数(比如说4.5),我能否重新计算平均值,使其变为:

int currentCount now equals 13
float currentScore now equals ?????

或者这是不可能的,我仍然需要记住分数列表吗?
6个回答

19
以下公式可让您仅从存储的平均值和计数跟踪平均值,正如您所请求的。
currentScore = (currentScore * currentCount + newValue) / (currentCount + 1)
currentCount = currentCount + 1

这取决于您的平均值当前是您的总和除以计数。因此,您只需将计数乘以平均值即可获得总和,添加新值并除以(count + 1),然后增加计数。

假设您有数据{7,9,11,1,12},并且您要保留的唯一内容是平均值和计数。每添加一个数字,您会得到:

+--------+-------+----------------------+----------------------+
| Number | Count |   Actual average     | Calculated average   |
+--------+-------+----------------------+----------------------+
|      7 |     1 | (7)/1           =  7 | (0 * 0 +  7) / 1 = 7 |
|      9 |     2 | (7+9)/2         =  8 | (7 * 1 +  9) / 2 = 8 |
|     11 |     3 | (7+9+11)/3      =  9 | (8 * 2 + 11) / 3 = 9 |
|      1 |     4 | (7+9+11+1)/4    =  7 | (9 * 3 +  1) / 4 = 7 |
|     12 |     5 | (7+9+11+1+12)/5 =  8 | (7 * 4 + 12) / 5 = 8 |
+--------+-------+----------------------+----------------------+

1
我担心舍入误差的积累。存储计数和总和,而不是运行平均值,可以减少这种误差(但不能完全消除它)。 - slim
Pax - 我应该使用什么类型的数据库字段? - Pure.Krome
@Pure,DB是指数据库吗?我不确定你在这里问什么。 - paxdiablo
@PureK,我会选择使用 FLOAT 类型。我的编程思想是尽可能简单地满足需求。任何数据库中的标准浮点型字段都足以存储信息。 - paxdiablo
非常棒!好多年前我尝试做这个的时候都觉得不可能,但我从没真正思考过它... 现在看起来非常酷。 - mpen
显示剩余3条评论

16

我喜欢存储总数和计数,这样可以避免每次多余的乘法运算。

current_sum += input;
current_count++;
current_average = current_sum/current_count;

1
这是一个关于保持总和的好观点,特别是如果你可以推迟平均值计算直到你把所有的数字都加起来。 - paxdiablo
但我们不应该把这变成一个互相吹捧的社会 :-) - paxdiablo
通常情况下,您可以使用幂的总和来计算第n个矩。例如,您可以使用平方和、总和和计数来计算标准差。但是,如果您需要流式标准差,请不要这样做,而应该使用以下方法:http://www.cs.berkeley.edu/~mhoemmen/cs194-fall2007/Tutorials/variance.pdf - John with waffle
1
而且你的头发很棒!哦,抱歉。我们决定不要成为互相欣赏的社团... - slim

3

其实很简单,只需看平均数的公式:A1 + A2 + ... + AN/N。如果你已知旧平均数和数字数量N,那么可以轻松地计算出新的平均数:

newScore = (currentScore * currentCount + someNewValue)/(currentCount + 1)

2
你可以存储currentCount和sumScore,然后计算sumScore/currentCount。

2

或者,如果你想要有趣一点,你可以在一行代码中完成:

 current_average = (current_sum = current_sum + newValue) / ++current_count;

:)


++current_count 和 current_count++ 有什么区别吗? - Pure.Krome
是的。一个在计算当前平均值之前增加 current_count,另一个在计算之后增加。 - slim
所以++current_count在除法完成之前递增,而current_count++在除法之后递增?哎呀!仅仅通过查看代码,我本以为它应该是...“将左边除以右边,即(当前计数+1)。很高兴我问了! - Pure.Krome
这在C或C++中是正确的。但在Java中不是。答案会因语言而异! - Bill Lynch

1

现在,浮点数变量currentScore等于(currentScore * (currentCount-1) + 4.5)/currentCount?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接