【问题标题】:Moving average produces array of different length?移动平均线产生不同长度的数组?
【发布时间】:2018-05-09 03:43:13
【问题描述】:

This question 有很多关于如何获得移动平均线的有用答案。 我已经尝试了 numpy 卷积和 numpy cumsum 两种方法,并且在示例数据集上都运行良好,但在我的真实数据上生成了一个较短的数组。

数据以0.01 分隔。示例数据集长度为50,真实数据数万。所以它一定是导致问题的窗口大小,我不太明白函数中发生了什么。

这是我定义函数的方式:

def smoothMAcum(depth,temp, scale): # Moving average by cumsum, scale = window size in m
    dz = np.diff(depth)  
    N = int(scale/dz[0])
    cumsum = np.cumsum(np.insert(temp, 0, 0)) 
    smoothed=(cumsum[N:] - cumsum[:-N]) / N 
    return smoothed

def smoothMAconv(depth,temp, scale): # Moving average by numpy convolution
    dz = np.diff(depth) 
    N = int(scale/dz[0])
    smoothed=np.convolve(temp, np.ones((N,))/N, mode='valid') 
    return smoothed

然后我实现它:

scale = 5.
smooth = smoothMAconv(dep,data, scale)

但是print len(dep), len(smooth) 返回81071 80572

如果我使用其他功能,也会发生同样的情况。 如何获得与数据长度相同的平滑数组?

为什么它在小数据集上起作用?即使我尝试不同的比例(并为示例和数据使用相同的比例),示例中的结果与原始数据具有相同的长度,但在实际应用程序中却不同。 我考虑了nan 值的影响,但如果我在示例中有nan,它没有任何区别。

如果没有完整的数据集,如果可能的话,问题出在哪里?

【问题讨论】:

  • 可以通过模拟数据(例如我的答案中的随机数组)包含一个具有大数据集的可重现示例。

标签: python numpy


【解决方案1】:

您的第二种方法很容易修改以保留长度,因为numpy.convolve 支持参数mode='same'

np.convolve(temp, np.ones((N,))/N, mode='same') 

这可以通过在两侧对数据集temp 进行零填充来实现,- 除非您的数据恰好在边界附近为 0,否则这将不可避免地对边界产生一些影响。示例:

N = 10
x = np.linspace(0, 2, 100)
y = x**2 + np.random.uniform(size=x.shape)
y_smooth = np.convolve(y, np.ones((N,))/N, mode='same') 
plt.plot(x, y, 'r.')
plt.plot(x, y_smooth)
plt.show()

零填充的边界效果在右端非常明显,数据点大约是4-5但被0填充。

要减少这种不良影响,请使用numpy.pad 进行更智能的填充;恢复到mode='valid' 进行卷积。焊盘宽度必须使得总共添加 N-1 个元素,其中 N 是移动窗口的大小。

y_padded = np.pad(y, (N//2, N-1-N//2), mode='edge')
y_smooth = np.convolve(y_padded, np.ones((N,))/N, mode='valid') 

用数组的边值填充看起来好多了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 2015-11-28
    • 2013-12-22
    • 1970-01-01
    • 2021-07-10
    • 2021-04-19
    相关资源
    最近更新 更多