不同长度时间序列数据上采样至9000点并保留原始形状的实现方法
脉冲类时间序列保形上采样到固定长度的可行方案
核心约束:所有上采样操作必须完整保留原始采样点的幅值、相对时间位置,禁止使用全局拟合修改原始数据,这是避免脉冲特征丢失的核心前提。
你之前采用的全局拟合方案失效的原因很明确:全局拟合本质是对全段数据做平滑化的最优逼近,会把脉冲这类局部陡变、窄宽度的特征视为离群点/噪声,自动压低峰值、拉缓上升沿/下降沿,甚至直接抹除占比极低的脉冲信号,这就是之前大量信息丢失的根本原因。
针对不同密度、不同形态的脉冲数据,可选择以下三类保形上采样方法,均可将所有数据统一上采样至9000个采样点且不丢失原有形状特征:
1. 分段线性插值(零特征偏移的基础方案)
- 适用场景:所有类型脉冲数据,尤其适配原始采样点稀疏的场景(比如你提到的仅200个采样点的data_1)
- 操作逻辑:
- 首先把每段原始数据的采样索引映射到[0,1]的归一化相对时间轴:长度为N的原始数据,第i个点的相对时间为
t_i = i/(N-1)(i从0到N-1) - 生成9000个目标采样点的相对时间:
T_j = j/(9000-1)(j从0到8999) - 对每个目标时间T_j,找到它落在原始哪两个相邻的时间点
t_i、t_{i+1}之间,通过线性插值计算对应幅值
- 首先把每段原始数据的采样索引映射到[0,1]的归一化相对时间轴:长度为N的原始数据,第i个点的相对时间为
- 保形原理:完全不修改任何原始采样点的幅值与相对位置,仅在相邻点之间补充采样,不会扭曲脉冲的峰值、陡变沿,没有任何额外平滑或偏移
- 缺点:如果原始采样稀疏,插值后的脉冲会呈现折线形态,没有连续平滑的过渡
2. 保形三次样条插值(PCHIP,平滑且保特征的进阶方案)
- 适用场景:原始采样密度较高的脉冲数据(比如你提到的7000采样点的data_2、3000采样点的data_3),需要插值后曲线更平滑的场景
- 操作逻辑:采用分段三次Hermite插值(PCHIP)替代普通三次样条,插值过程中约束曲线不会超出原始相邻点的幅值区间
- 保形原理:避免了普通三次样条在陡变位置的过冲问题,同时保留原始数据的斜率变化,不会把脉冲的陡上升沿/下降沿拉缓,也不会产生多余的假峰值或谷值
- 优势:比线性插值的曲线更平滑,同时完全保留脉冲的形状特征,不会出现全局拟合的失真问题
3. 最近邻插值(适配数字式陡变脉冲)
- 适用场景:高低电平完全跳变的数字脉冲、窄脉冲沿极陡的场景,以及原始采样极稀疏的情况
- 操作逻辑:每个目标采样点的幅值直接取距离最近的原始采样点的幅值
- 保形原理:完全保留脉冲的阶跃形态,没有任何过渡变形,不会把陡变的跳变沿拉成斜线,最适合离散的数字脉冲信号
实操注意事项
- 所有操作优先按归一化相对时间轴映射,避免不同长度数据的脉冲相对位置错位;如果你的数据有实际物理时间戳,需要直接用时间戳映射,而非采样序号
- 上采样完成后不要额外做平滑滤波,任何平滑操作都会磨平脉冲的陡变特征
- 不要使用普通三次样条、双三次等高阶全局插值,这类插值容易在脉冲陡变位置产生过冲,扭曲原有形状
- 方法选择优先级:
- 原始采样点数 < 500:优先选分段线性插值
- 原始采样点数 ≥ 500且需要平滑曲线:选PCHIP
- 纯数字跳变脉冲:选最近邻插值
参考代码示例(Python)
import numpy as np from scipy.interpolate import PchipInterpolator, interp1d # 目标上采样长度 TARGET_LENGTH = 9000 target_time = np.linspace(0, 1, TARGET_LENGTH) def upsample_pulse(original_data, method="linear"): # 原始数据映射到0-1的相对时间轴 original_time = np.linspace(0, 1, len(original_data)) if method == "linear": interp_func = interp1d(original_time, original_data, kind="linear") elif method == "pchip": interp_func = PchipInterpolator(original_time, original_data) elif method == "nearest": interp_func = interp1d(original_time, original_data, kind="nearest") return interp_func(target_time) # 调用示例 # data_1 = np.load("your_data_1.npy") # upsampled_data1 = upsample_pulse(data_1, method="linear")
内容的提问来源于stack exchange,提问作者joe
相关产品推荐
相关产品推荐

