矢量滑动/滚动numpy nanmean

问题描述

我目前正在使用此代码进行移动窗口平均:

n=500

x_copy=np.hstack((np.full(n,np.nan),copy.deepcopy(x),np.full(n,np.nan)))

x_values=[]
for i in range(n,len(x)+n):
    x_values.append(np.nanmean(x[i-n:i+n+1]))

plt.plot(x_values)

使用x我正在处理的数组,并且n是窗口长度的一半。但是,我需要快速执行此操作,因为我必须执行此操作的大约4400 * 10,并且数组的长度约为60000个元素。搜索了一段时间后,我发现np.convolve应该可以工作,所以我改用以下代码

plt.plot(np.convolve(x,np.ones(((2*n),))/(2*n),mode='valid'),zorder=2)

虽然这确实非常快,但它并没有完全满足我的要求,因为它似乎在数组末尾停止了500*2个单元。作为参考,下面是它们两者的图形图像:蓝色是我自己的代码,橙色是卷积。我想用卷积加快平均移动窗口的速度,虽然我不知道如何。

Reference

解决方法

将那些NaNs设置为0s,然后在那些被屏蔽的版本上使用np.convolve-

# Window-size
W = 2*n+1

# Non-nans mask
m = ~np.isnan(x)

# "Masked" input array
x0 = np.where(m,x,0)

# Setup conv kernel and perform conv on x0 and mask m for the counts to divide
K = np.ones(W)
out = (np.convolve(x0,K)/np.convolve(m,K))[W-1:]