Python-均线或均线

发布于 2021-02-02 23:15:35

是否有python的scipy函数或numpy函数或模块来计算给定特定窗口的一维数组的运行平均值?

关注者
0
被浏览
49
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    对于一个简短,快速的解决方案,它可以在一个循环中完成所有事情,而没有依赖关系,下面的代码效果很好。

    mylist = [1, 2, 3, 4, 5, 6, 7]
    N = 3
    cumsum, moving_aves = [0], []
    
    for i, x in enumerate(mylist, 1):
        cumsum.append(cumsum[i-1] + x)
        if i>=N:
            moving_ave = (cumsum[i] - cumsum[i-N])/N
            #can do stuff with moving_ave here
            moving_aves.append(moving_ave)
    


  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    高效的解决方案
    卷积比简单方法好得多,但是(我猜)它使用FFT,因此速度很慢。但是专门用于计算运行,以下方法可以正常工作

    def running_mean(x, N):
        cumsum = numpy.cumsum(numpy.insert(x, 0, 0)) 
        return (cumsum[N:] - cumsum[:-N]) / float(N)
    

    要检查的代码

    In[3]: x = numpy.random.random(100000)
    In[4]: N = 1000
    In[5]: %timeit result1 = numpy.convolve(x, numpy.ones((N,))/N, mode='valid')
    10 loops, best of 3: 41.4 ms per loop
    In[6]: %timeit result2 = running_mean(x, N)
    1000 loops, best of 3: 1.04 ms per loop
    

    注意numpy.allclose(result1, result2)True,这两种方法是等效的。N越大,时间差越大。



  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。


    UPD:Alleo和jasaarim提出了更有效的解决方案。

    你可以使用np.convolve

    np.convolve(x, np.ones((N,))/N, mode='valid')
    

    说明
    运行平均值是卷积数学运算的一种情况。对于移动平均值,你可以沿输入滑动窗口并计算窗口内容的平均值。对于离散的一维信号,卷积是相同的事情,除了用平均值代替之外,你还可以计算任意线性组合,即将每个元素乘以相应的系数并相加结果。窗口中每个位置对应的那些系数有时称为卷积核。现在,N个值的算术平均值为(x_1 + x_2 + ... + x_N) / N,因此对应的内核为(1/N, 1/N, ..., 1/N),这正是我们使用所得到的np.ones((N,))/N。

    边缘
    的mode参数np.convolve指定如何处理边缘。我在valid这里选择此模式是因为我认为大多数人都希望运行平均值起作用,但是你可能还有其他优先事项。这是说明两种模式之间差异的图表:

    import numpy as np
    import matplotlib.pyplot as plt
    modes = ['full', 'same', 'valid']
    for m in modes:
        plt.plot(np.convolve(np.ones((200,)), np.ones((50,))/50, mode=m));
    plt.axis([-10, 251, -.1, 1.1]);
    plt.legend(modes, loc='lower center');
    plt.show()
    
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看