如何为numpy一维信号数组中的离散信号点增加指定宽度
操作标准名称
该操作属于信号处理与数学形态学范畴,标准名称为灰度形态学膨胀(Grayscale Dilation),在一维离散峰值信号处理场景下也常被称为峰值展宽。它的核心逻辑是用指定长度的结构模板遍历信号,将每个非零信号点的取值覆盖到以其为中心的邻域范围内,完全匹配你的需求。
最高效实现方法
基于Numpy的向量化操作实现是最高效的方案,完全规避Python层循环,时间复杂度仅为O(n)(n为数组长度),实现思路如下:
- 提取所有非零信号的索引位置和对应取值
- 计算宽度对应的半长偏移量:因width为奇数,偏移范围为
[- (width//2) , width//2] - 批量生成所有需要填充的位置索引,过滤掉超出数组边界的无效索引后直接赋值,天然保证数组总长度不变
代码实现
Numpy原生实现(无第三方依赖)
import numpy as np def broaden_signal(arr, width): assert width % 2 == 1 and width > 0, "width必须为正奇数" half_w = width // 2 arr_len = len(arr) # 提取非零信号的索引和值 non_zero_idx = np.where(arr != 0)[0] non_zero_vals = arr[non_zero_idx] # 生成偏移量矩阵和填充位置 offsets = np.arange(-half_w, half_w + 1) fill_pos = non_zero_idx[:, None] + offsets # 过滤边界外的无效位置 valid_mask = (fill_pos >= 0) & (fill_pos < arr_len) valid_fill_pos = fill_pos[valid_mask] # 生成对应填充值 valid_fill_vals = np.repeat(non_zero_vals, width)[valid_mask.flatten()] # 输出结果 res = np.zeros_like(arr) res[valid_fill_pos] = valid_fill_vals return res # 测试用例 arr = np.array([0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,5,0,0,0,1,0,0,0,0,0,0,0,0,0,0]) print(broaden_signal(arr, width=3)) # 输出:[0 0 0 0 1 1 1 0 0 2 2 2 0 0 5 5 5 0 1 1 1 0 0 0 0 0 0 0 0 0]
现成接口调用
如果允许引入scipy依赖,可直接调用封装好的灰度膨胀接口,效率和原生Numpy实现相当,且自动处理信号重叠时保留最大值的逻辑:
from scipy.ndimage import grey_dilation res = grey_dilation(arr, size=width)
内容的提问来源于stack exchange,提问作者Mike Azatov
相关产品推荐
相关产品推荐

