我不断在Python中添加/删除元组列表,并且对加权平均值(不是列表本身)感兴趣。由于这部分在计算上与其他部分相比非常昂贵,我想优化它。什么是跟踪加权平均值的最佳方法?我可以想到两种方法:
我更喜欢第二种选择,但我担心"浮点错误"通过恒定加/减来诱导。处理这个问题的最佳方法是什么?
答案 0 :(得分:1)
尝试以整数形式进行吗? Python bignums应该为理性数字做出理性的论证(对不起,已经很晚了......真的很遗憾)。
这实际上取决于您使用的术语数量以及您的加权系数与天气的关系,您会遇到很多浮点漂移。你只需要53位精度,你可能不需要那么多。
如果你的加权因子小于1,那么你的错误应该是有限的,因为你不断减少它。假设你的体重是0.6
(可怕,因为你无法用二进制表示)。这是0.00110011...
表示为0.0011001100110011001101
(在最后一位舍入)。因此,您从该舍入引入的任何错误将在您再次相乘后减少。最新术语中的错误将占主导地位。
在你需要之前不要做最后的分工。再次给出0.6作为你的体重和10个术语,你的学期权重将是第一学期的99.22903012752124
一直到最后一学期的0.6**-t
。将您的新字词乘以99.22...
,将其添加到您的运行总和并减去结尾字词,然后除以246.5725753188031(sum([0.6**-x for x in range(0,10)]
)
如果您真的想要进行调整,可以在要删除的术语中添加ULP,但我认为这只是故意低估。
答案 1 :(得分:0)
这是一个保留浮动点以保持总计的答案 - 我认为加权平均值只需要两个运行总计:
分配一个数组来存储你的数字,这样插入数字意味着在数组中找到一个空的空格并将其设置为该值并删除数字意味着将数组中的值设置为零并将该空间声明为空 - 您可以使用空闲条目的链接列表在时间O(1)
中查找空条目现在你需要计算一个大小为N的数组的总和。将数组视为完整的二进制树,如在heapsort中,所以offset 0是根,1和2是它的子节点,3和4是1,5和6的孩子是2的孩子,依此类推 - 我的孩子是2i + 1和2i + 2。
对于每个内部节点,保留树中该节点或其下的所有条目的总和。现在,当你修改一个条目时,你可以通过从该条目到树的根目录的方式重新计算数组中的值的总和,在你去的时候纠正部分总和 - 这会花费你O(log N)其中N是数组的长度。