如何用Python去除输出信号中相位一致的周期性噪声
实现步骤与代码
核心问题修复
你之前的方案存在3个关键问题导致效果不符合预期:
- 重采样后未做缺失值插值,产生数据缺口
- 未对噪声信号做振幅增益与直流偏移校准,直接相减会残留振荡甚至放大波动
- 未匹配两个信号的微小相位差,导致振荡抵消不完全
完整实现代码
接你已经读取完time_list_thick、thick、time_list_temp_qcm、temp_qcm变量后的代码:
import numpy as np import pandas as pd from scipy.optimize import minimize # 1. 构建统一时间网格的重采样信号,插值补全缺失值 # 转换为时间索引Series signal_series = pd.Series(thick, index=pd.to_timedelta(time_list_thick, unit='s')) noise_series = pd.Series(temp_qcm, index=pd.to_timedelta(time_list_temp_qcm, unit='s')) # 取两个信号的时间重叠区间作为统一时间范围 start_time = max(signal_series.index.min(), noise_series.index.min()) end_time = min(signal_series.index.max(), noise_series.index.max()) # 重采样到0.1秒粒度(比原来的采样率更高,减少信息损失),线性插值补全 resample_freq = '100L' # 100毫秒,可根据你的采样间隔调整 signal_resampled = signal_series.resample(resample_freq).mean().interpolate(method='linear')[start_time:end_time] noise_resampled = noise_series.resample(resample_freq).mean().interpolate(method='linear')[start_time:end_time] # 2. 最小二乘拟合噪声的最优增益与偏移量 # 目标函数:最小化 signal - (a*noise + b) 的方差 def loss_func(params): a, b = params return np.sum((signal_resampled.values - (a * noise_resampled.values + b))**2) # 初始参数猜测:a默认1,b默认两个信号均值差 init_params = [1, np.mean(signal_resampled) - np.mean(noise_resampled)] opt_params = minimize(loss_func, init_params).x a_opt, b_opt = opt_params # 3. 计算去噪后的真实平稳信号 denoised_signal = signal_resampled - (a_opt * noise_resampled + b_opt) # 可选:加一个小窗口的移动平均进一步平滑残留小波动 # denoised_signal = denoised_signal.rolling(window=10, center=True).mean().dropna() # 4. 结果绘图验证 import matplotlib.pyplot as plt fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 10)) # 原始信号 ax1.plot(signal_resampled.index.total_seconds(), signal_resampled.values, label='原始输出信号', c='blue') ax1.plot(noise_resampled.index.total_seconds(), a_opt*noise_resampled.values + b_opt, label='校准后噪声', c='green') ax1.legend() ax1.set_ylabel('振幅') ax1.set_title('原始信号与校准后噪声') # 去噪后信号 ax2.plot(denoised_signal.index.total_seconds(), denoised_signal.values, label='去噪后信号', c='red') ax2.legend() ax2.set_xlabel('时间(s)') ax2.set_ylabel('振幅') ax2.set_title('去噪后平稳信号') plt.tight_layout() plt.show()
可选优化
如果两个信号存在微小相位差导致振荡抵消不完全,可以先通过互相关计算最优相位偏移量,将噪声信号平移对应时间后再做拟合,进一步提升抵消效果:
from scipy.signal import correlate # 计算互相关找最优偏移 corr = correlate(signal_resampled.values, noise_resampled.values, mode='same') opt_shift = np.argmax(corr) - len(corr)//2 # 噪声平移后再做后续校准 noise_shifted = noise_resampled.shift(opt_shift).dropna() # 对齐平移后的信号长度 signal_aligned = signal_resampled.loc[noise_shifted.index]
内容的提问来源于stack exchange,提问作者tjsmert44
相关产品推荐
相关产品推荐

