【问题标题】:Simple rolling average - first few values简单滚动平均值 - 前几个值
【发布时间】:2018-04-02 19:03:05
【问题描述】:

我写了一个简单的滚动平均函数,效果很好。我也不想使用像 numpy 或 pandas 这样的外部库,你知道的。

def get_rolling_average(data, period):

  rolling = []
  for i in range (0, len(data)):

    end = i + period
    nums = data[i:end]

   # if i < (period-1):
   # nums = data[0:i+1]
   # rolling.append(mean(nums))

    if len(nums) == period:
      rolling.append(mean(nums))

  return rolling

def round_nicely(num, places):
  return round(num, places)

def mean(lst):
  summ = sum(lst[0:len(lst)])
  summ = float(summ)
  return round_nicely(summ/len(lst),1)


print("Rolling average!")

xl = [45, 51, 73, 82, 76, 56, 57, 78, 89, 59]
print get_rolling_average(xl, 3)

结果是

Rolling average!
[56.3, 68.7, 77.0, 71.3, 63.0, 63.7, 74.7, 75.3]

但是,如果前几个值小于句点,我想包括它们。在这个例子中,它只是 45 和 48。

Rolling average!
[45.0, 48.0, 56.3, 68.7, 77.0, 71.3, 63.0, 63.7, 74.7, 75.3]

 where
 (45)/1 = 45.0
 (45 + 51)/2 = 48.0

我不确定最 Pythonic 的方法来做到这一点。我有点头脑发热,我最有凝聚力的尝试是注释掉的三行,但它跳过了一个值。

【问题讨论】:

标签: python arrays python-2.7 average


【解决方案1】:

你很亲密。尝试如下修改您现有的功能。

def get_rolling_average(data, period):

  rolling = []

  for i in range (0, len(data)):

    nums = data[i-period+1:i+1]

    if i < period-1:
      rolling.append(mean(data[:i+1]))

    if (i >= period-1) and (len(nums) == period):
      rolling.append(mean(nums))

  return rolling

返回:

[45.0, 48.0, 56.3, 68.7, 77.0, 71.3, 63.0, 63.7, 74.7, 75.3]

说明

  • 您需要 i &lt; period-1i &gt;= period-1 的特定逻辑。以这种方式构建您的逻辑。
  • 定义 nums = data[i-period:i] 以使您能够捕获 3 个值的所有分组。

一旦您对该解决方案感到满意,您可能希望了解替代实现,例如itertools, numpy, pandas.

【讨论】:

    【解决方案2】:

    一种方法是使用itertoolschain 的多个标记值到原始列表的3 路tee,例如:

    In []:
    xl = [45, 51, 73, 82, 76, 56, 57, 78, 89, 59]
    ts = [it.chain([0]*c, t) for c, t in enumerate(it.tee(xl, 3))]
    [sum(x)/sum(1 for i in x if i) for x in it.zip_longest(*ts, fillvalue=0)]
    
    Out[]:
    [45.0,
     48.0,
     56.333333333333336,
     68.66666666666667,
     77.0,
     71.33333333333333,
     63.0,
     63.666666666666664,
     74.66666666666667,
     75.33333333333333,
     74.0,
     59.0]
    

    如果0 是列表中的有效值,那么您可以使用另一个哨兵并明确地将filter 取出。

    或者,您可以将collections.dequemaxlen=3 一起使用,例如:

    In []:
    from collections import deque
    
    d = deque(maxlen=3)
    r = []
    for x in xl:
        d.append(x)
        r.append(sum(d)/len(d))
    for _ in range(len(d)-1):
        d.popleft()
        r.append(sum(d)/len(d))
    r
    
    Out[]:
    [45.0,
     48.0,
     56.333333333333336,
     68.66666666666667,
     77.0,
     71.33333333333333,
     63.0,
     63.666666666666664,
     74.66666666666667,
     75.33333333333333,
     74.0,
     59.0]
    

    【讨论】:

      猜你喜欢
      • 2020-03-07
      • 2017-12-26
      • 2021-02-08
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      • 2021-07-03
      • 1970-01-01
      相关资源
      最近更新 更多