Python 移动平均产生不同长度的数组?

Python 移动平均产生不同长度的数组?,python,numpy,Python,Numpy,有很多关于如何获得移动平均线的有用答案。 我尝试了numpy卷积和numpy求和这两种方法,它们在示例数据集上都很好地工作,但在实际数据上生成了一个较短的数组 数据的间距为0.01。示例数据集的长度为50,实际数据为数万。所以一定是窗口大小的问题导致了这个问题,我不太明白函数中发生了什么 我是这样定义函数的: def smoothMAcum(depth,temp, scale): # Moving average by cumsum, scale = window size in m d

有很多关于如何获得移动平均线的有用答案。 我尝试了numpy卷积和numpy求和这两种方法,它们在示例数据集上都很好地工作,但在实际数据上生成了一个较短的数组

数据的间距为
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)
但是
打印透镜(dep),透镜(平滑)
返回
8107180572

如果我使用另一个函数,也会发生同样的情况。 如何获得与数据长度相同的平滑数组

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


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

第二种方法很容易修改以保留长度,因为它支持参数
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填充

为了减少这种不想要的效果,使用更智能的填充;正在还原到卷积的
模式='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') 


按数组的边值填充看起来更好。

第二种方法很容易修改以保留长度,因为它支持参数
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填充

为了减少这种不想要的效果,使用更智能的填充;正在还原到卷积的
模式='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') 


通过数组的边值填充看起来更好。

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