【问题标题】:Average of each consecutive segment in a list列表中每个连续段的平均值
【发布时间】:2019-02-10 20:18:44
【问题描述】:

我有一个清单:

sample_list = array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])

我想计算每个元素的平均值,比如 4 个元素。但不是单独的 4 个元素,而是前 4 个:

1,2,3,4

接着是:

2,3,4,5

接着是:

3,4,5,6

等等。

结果将是第一个列表中每 4 个元素之间的平均值的数组或列表。

输出:

array([2.5, 3.5, 4.5, ...])

我的尝试:

sample_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
splits = 4

def avgerage_splits(data):
    datasum = 0
    count = 0 
    for num in data:
        datasum += num
    count += 1
    if count == splits: 
        yield datasum / splits
        datasum = count = 0
if count: 
    yield datasum / count

print(list(average_splits(sample_list)))

[1.5, 3.5, 5.5, 7.5, 9.5, 11.0]

这不是我需要的输出,因为它会在移动到一组新的 4 个元素之前计算每 4 个元素的平均值。我只想在列表中向上移动一个元素并计算这 4 个元素的平均值,依此类推。

【问题讨论】:

    标签: python list numpy average


    【解决方案1】:

    如果numpy 是一个选项,实现此目的的一种简单方法是使用np.convolve,它可用于在与np.ones 的数组进行卷积时计算滚动平均值

    import numpy as np
    sample_list = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], dtype=float)
    
    w = 4
    np.convolve(sample_list, np.ones(w), 'valid') / w
    

    输出

    array([ 2.5,  3.5,  4.5,  5.5,  6.5,  7.5,  8.5,  9.5, 10.5, 11.5, 12.5,
       13.5, 14.5])
    

    详情

    np.convolve 在两个输入数组之间执行discrete convolution。在本例中为np.ones(w),它将是与指定窗口长度(本例中为 4)array([1., 1., 1., 1.])sample_list 一样多的数组。

    以下列表理解旨在复制np.convolve 计算输出值的方式:

    w = 4
    np.array([sum(ones*sample_list[m:m+w]) for m in range(len(sample_list)-(w-1))]) / w 
    
    array([ 2.5,  3.5,  4.5,  5.5,  6.5,  7.5,  8.5,  9.5, 10.5, 11.5, 12.5,
       13.5, 14.5])
    

    因此,在每次迭代中,它都会取一数组与sample_list 的当前 窗口 之间的内积。

    下面是如何计算第一个输出的示例,以便更清楚一点。请注意,在这种情况下,为卷积指定的使用模式是valid,这意味着,重叠被指定为始终完整:

    [1,1,1,1]
    [1,2,3,4,5,6,7,8...]
    = (1*1 + 1*2 + 1*3 + 1*4) / 4 = 2.5
    

    以下为:

      [1,1,1,1]
    [1,2,3,4,5,6,7,8...]
    = (1*2 + 1*3 + 1*4 + 1*5) / 4 = 3.5
    

    依此类推,如前所述,产生sample_list移动平均线

    【讨论】:

    • 你能解释一下 np.ones() 的作用吗?
    • 这对@Murray 有帮助吗?请记住,如果有,您可以投票/接受,请参阅What should I do when someone answers my question?
    • 是的,这很有帮助。 “移动平均线”正是我想要的。赞成并接受。非常感谢。
    【解决方案2】:

    您可以使用单行列表推导:

    avgs = [sum(sample_list[i:i + splits]) / splits for i in range(len(sample_list) - splits + 1)]
    

    当然,如果您想要生成器,请将方括号替换为圆括号。

    【讨论】:

      【解决方案3】:

      您可以将函数 mean() 映射到压缩迭代器:

      from statistics import mean
      from itertools import islice
      
      l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
      
      zip_iter = zip(*(islice(l, i, None) for i in range(4)))
      list(map(mean, zip_iter))
      # [2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5]
      

      【讨论】:

        【解决方案4】:

        作为一个对大多数 python 模块知之甚少的新程序员,这里有另一种解决方案。 4是分裂的数量。它总是可以调整你想要的任意数量的分割。虽然 3 in (Len(nlis) - 3) 是 4 - 1。所以用你的分割数替换 3 - 1。

        nlis = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
        
        summation = []
        ave = []
        for a in range(len(nlis)- 3):
            summation = sum(nlis[a:a+4])
            ave.append(summation/4)
        print(ave)
        
        # [2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-10-15
          • 1970-01-01
          • 1970-01-01
          • 2017-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-29
          相关资源
          最近更新 更多