If you want a moving average, take a look at scipy.ndimage.convolve1d
. A sliding window is just convolution with a box function of the appropriate width and height.
You are looking for something like
def windowed_mean(arr, n, axis=-1):
box = np.full(n, 1.0 / n)
return ndimage.convolve1d(arr, box, axis)
This will return an array of the same size as the original. You likely want something that does not include the partially convolved elements, so you can trim (n - 1) // 2
from the left and n // 2
from the right. Using integer division like that ensures that the trim is correct for both even and odd windows:
return ndimage.convolve1d(arr, box, axis)[..., (n - 1) // 2:-(n // 2)]
You can do the same convolution using a 1D convolver like np.convolve
. This would require your data to be arranged so that the dimension over which you are convolving is contiguous. This is likely the case here, since numpy uses C order by default:
def windowed_mean(arr, n):
box = np.full(n, 1.0 / n)
conv = np.convolve(arr.ravel(), box)
return conv[n - 1:].reshape(arr.shape)[..., :1 - n]
To operate over not-the-last dimension, you would have to move the axis of interest to the end. Keep in mind that ravel
will make a copy of the data in that case:
def windowed_mean(arr, n, axis=-1):
box = np.full(n, 1.0 / n)
a = np.moveaxis(arr, axis, -1).ravel()
conv = np.convolve(a, box)
conv = conv[n - 1:].reshape(arr.shape)[..., :1 - n]
return np.moveaxis(conv, -1, axis)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…