在Python中运行平均值

Nat*_*ohl 13 python list-comprehension moving-average

是否有一种pythonic方法来构建包含某些函数的运行平均值列表

在阅读了一篇关于火星人,黑匣子和柯西分布的有趣小块之后,我认为自己计算Cauchy分布的平均值会很有趣:

import math 
import random

def cauchy(location, scale):
    p = 0.0
    while p == 0.0:
        p = random.random()
    return location + scale*math.tan(math.pi*(p - 0.5))

# is this next block of code a good way to populate running_avg?
sum = 0
count = 0
max = 10
running_avg = []
while count < max:
    num = cauchy(3,1)
    sum += num
    count += 1
    running_avg.append(sum/count)

print running_avg     # or do something else with it, besides printing
Run Code Online (Sandbox Code Playgroud)

我认为这种方法有效,但我很好奇是否可能有更优雅的方法来构建running_avg列表而不是使用循环和计数器(例如列表推导).

有一些相关的问题,但它们解决了更复杂的问题(小窗口大小,指数加权)或者不是Python特有的:

ori*_*rip 15

你可以写一个发电机:

def running_average():
  sum = 0
  count = 0
  while True:
    sum += cauchy(3,1)
    count += 1
    yield sum/count
Run Code Online (Sandbox Code Playgroud)

或者,给定Cauchy数的生成器和运行和生成器的实用函数,您可以拥有一个整洁的生成器表达式:

# Cauchy numbers generator
def cauchy_numbers():
  while True:
    yield cauchy(3,1)

# running sum utility function
def running_sum(iterable):
  sum = 0
  for x in iterable:
    sum += x
    yield sum

# Running averages generator expression (** the neat part **)
running_avgs = (sum/(i+1) for (i,sum) in enumerate(running_sum(cauchy_numbers())))

# goes on forever
for avg in running_avgs:
  print avg

# alternatively, take just the first 10
import itertools
for avg in itertools.islice(running_avgs, 10):
  print avg
Run Code Online (Sandbox Code Playgroud)


Mar*_*rot 6

你可以使用协同程序.它们类似于生成器,但允许您发送值.Coroutines是在Python 2.5中添加的,所以这在之前的版本中不起作用.

def running_average():
    sum = 0.0
    count = 0
    value = yield(float('nan'))
    while True:
        sum += value
        count += 1
        value = yield(sum/count)

ravg = running_average()
next(ravg)   # advance the corutine to the first yield

for i in xrange(10):
    avg = ravg.send(cauchy(3,1))
    print 'Running average: %.6f' % (avg,)
Run Code Online (Sandbox Code Playgroud)

作为列表理解:

ravg = running_average()
next(ravg)
ravg_list = [ravg.send(cauchy(3,1)) for i in xrange(10)]
Run Code Online (Sandbox Code Playgroud)

编辑:

  • 使用next()函数而不是it.next()方法.这样它也可以与Python 3一起使用.该next()函数也被反向移植到Python 2.6+.
    在Python 2.5中,您既可以使用替换调用it.next(),也可以next自己定义函数.
    (感谢Adam Parkin)