求带固定端点的Boxcar平滑函数(边界窗口尺寸递减)
符合边界条件的Boxcar平滑方案
一、现有库函数实现(推荐)
Pandas Rolling 方法
直接使用Pandas的滚动窗口功能,通过参数设置即可实现你需要的边界窗口收缩效果:
import pandas as pd import numpy as np # 示例数组 arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]) window_size = 5 # 生成平滑结果 smoothed = pd.Series(arr).rolling( window=window_size, center=True, min_periods=1 ).mean().values print(smoothed) # 输出:[1. 2. 3. 4. 5. 6. 7. 8. 9.]
该实现完全匹配需求:端点保留原值,靠近端点的元素使用逐步扩大/缩小的窗口计算均值,中间元素使用完整窗口滑动平均。
SciPy 适配说明
scipy.ndimage.uniform_filter1d默认边界处理(如mode='reflect')会填充数组,无法直接实现窗口收缩效果。若要使用SciPy,需手动截取边界窗口计算均值,便捷性不如Pandas方案。
二、自定义高性能Python函数
如果不想依赖Pandas,可使用Numpy滑动窗口视图实现高性能自定义函数:
import numpy as np def boxcar_smooth(arr, window_size): n = len(arr) half_win = window_size // 2 smoothed = np.zeros(n, dtype=np.float64) # 左边界:窗口从1逐步扩大到完整窗口 for i in range(half_win + 1): smoothed[i] = arr[:i + half_win + 1].mean() # 中间区域:完整滑动窗口均值(向量化计算,性能最优) if n > window_size: sliding_windows = np.lib.stride_tricks.sliding_window_view(arr, window_size) smoothed[half_win : n - half_win] = sliding_windows.mean(axis=1) # 右边界:窗口从完整窗口逐步缩小到1 for i in range(n - half_win, n): smoothed[i] = arr[i - half_win:].mean() return smoothed # 测试 arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]) print(boxcar_smooth(arr, 5)) # 输出:[1. 2. 3. 4. 5. 6. 7. 8. 9.]
该函数通过向量化处理中间区域,仅边界使用少量循环,整体性能接近库函数水平。
内容的提问来源于stack exchange,提问作者Victor Savenije
相关产品推荐
相关产品推荐

