【发布时间】:2014-10-05 16:00:46
【问题描述】:
我的基本想法是创建一个链表,当每个新值进入时,将新值加 1/N 倍并减去第一个值的 1/N 倍,然后将指向 first 的指针移动 1 并释放与 first 相关联的内存。
这最终不会在 Python 中实现,只是为了让我的头脑清晰,我尝试用 Python 编写它,但我的实现存在缺陷。我需要一个双向链表吗?有没有更好的替代方法(不是基于链表)?
这是我目前的尝试:
class Link:
def __init__(self,val):
self.next = None
self.value = val
class LinkedList:
def __init__(self,maxlength):
self.current_link = None
self.maxlength = maxlength
self.sum = 0.
self.average = None
self.length = 0
self._first_link = None
def add_link(self,val):
new_link = Link(val)
new_link.next = self.current_link
self.current_link = new_link
if self._first_link is None:
self._first_link = self.current_link
self.sum += val
if self.length < self.maxlength:
self.length += 1
else:
self.sum -= self._first_link.value
self._first_link = self._first_link.next # this line is flawed
self.average = self.sum/self.length
def get_first(self):
return self._first_link.value
# Main
ll = LinkedList(5)
for ii in xrange(10):
ll.add_link(ii)
print ii,ll.get_first(),ll.average
问题是 _first_link 被设置为一个没有下一个的值。也就是说,_first_link 被设置为添加的第一个项目,但它的下一个是 None,所以我看不到如何将它移动 1。这就是让我怀疑是否需要双向链表的原因。
如果有任何建议,我将不胜感激。
【问题讨论】:
-
您要解决的实际问题是什么?我经常发现对这类东西使用指数移动平均线效果非常好,并且很容易以简单而高效的方式实现:en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
-
另外,如果您的值的幅度变化很大,您的方法可能会受到数值问题的影响,因为在浮点数学中,
((A+B)-A)-B不一定为零。 -
是的,我同意补偿求和或其他东西可能有助于数值准确性,但我并不担心(动态范围不大)。我要解决的问题只是我想计算一个时间序列中最后 1000 个数字的平均值,其中包含数千亿个值,所以我不想存储所有值在一个数组中。它甚至比指数移动平均线更简单——它只是我想要的平坦移动平均线。
-
我的观点是指数移动平均线实际上比滑动窗口更容易实现,因为它不需要保留任何过去的值(最近的平均值除外)。
标签: python linked-list