我目前有来自序列化数据的多个[Average, Count]
对。用户希望能够将一些值集合合并(分组)并获得汇总结果。
我很容易,我会Sum(Average * Count) / Sum(Count)
但是问题是,有些值非常大,如果我将所有值加起来就会引起算术溢出。
是否有一种方法可以合并平均部分而不计算总和?计数部分非常明显。
答案 0 :(得分:0)
假设Count
和Average
是索引值,则可以通过以下方式计算汇总平均值:
TotalCount = Sum(Count)
TotalAverage = Sum(Average * (Count/TotalCount))
如果要在序列化数据上的一次迭代中计算值,则可以采用类似于指数平均值的方式对连续的加权平均值求和。
TotalCount = 0
TotalAverage = 0
for each index in data-set of [Average, Count]
TotalCount = TotalCount + Count[index]
Weight = Count[index]/TotalCount
TotalAverage = TotalAverage * (1 - Weight)
+ Average[index] * Weight
您可以通过考虑前两对来得出正确的方法。
如果只有第一对:
TotalCount = Count[1]
TotalAverage = Average[1]
但是,如果有两对:
TotalCount = Count[1] + Count[2]
TotalAverage = Average[1] * (Count[1]/TotalCount)
+ Average[2] * (Count[2]/TotalCount)
如果我们从第一对迭代到第二对,那么两对计算可能像这样:
TotalCount = TotalCount + Count[2]
TotalAverage = TotalAverage * (TotalCount - Count[2])/TotalCount
+ Average[2] * (Count[2]/TotalCount)
如果我们用Weight
代表Count[2]/TotalCount
,则以上内容简化为:
TotalCount = TotalCount + Count[2]
Weight = Count[2]/TotalCount
TotalAverage = TotalAverage * (1 - Weight)
+ Average[2] * Weight
由于TotalCount
和TotalAverage
在获取一对新的序列化数据的每一步都是正确的,因此[2]
可以用迭代索引代替。
答案 1 :(得分:0)
虽然@jxh的回答很好并且可以解决您的问题,但是他和您的原始方法对数据进行了两次传递(首先是总计数,然后是平均值),这可能会损害性能。您可以一次通过,进行滚动平均。即使成对来自流,也可以使用它,而您不知道这里有多少对
一些Python代码:
data = [(3.1, 12), (5.2, 17), (9.7, 11)]
total_count = 0
total_avg = 0.0
for avg, count in data:
n0 = total_count
total_count += count
p = float(n0) / float(total_count)
total_avg = p*total_avg + (1.0 - p)*avg
print(total_count)
print(total_avg)