如何为curve_fit的damped_sine拟合设置数据截断范围?
阻尼正弦拟合排除噪声段干扰+全区间绘图实现方案
核心逻辑很简单:拟合和绘图是两个独立步骤,不需要用同一份数据集。只需要把x≤20的有效数据子集传给拟合函数计算参数,绘图时用全范围x代入拟合好的函数生成曲线即可,完全不需要裁剪原始数据或者缩小绘图范围。
具体修改点
- 原有数据转numpy数组、定义
damped_sine函数的逻辑不需要改动 - 新增布尔掩码,筛选出x值≤20的样本作为拟合专用数据集,噪声段数据完全不进入
curve_fit的计算流程 - 拟合完成后,不要用筛选后的短x数组生成拟合曲线,直接把完整的原始x数组传入拟合函数,计算得到覆盖全区间(包括x>20噪声段)的拟合y值
- 绘图逻辑和原有逻辑基本一致,正常绘制全量原始数据、全区间红色拟合曲线即可,还可以额外加一条参考线标记有效数据阈值
完整实现代码
import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt # 原始数据转numpy数组,和原有逻辑一致 x = np.array(x0) y = np.array(y0) # 定义阻尼正弦拟合模型,和原有逻辑一致 def damped_sine(t, A, decay_lambda, omega): return A * np.exp(-decay_lambda * t) * np.cos(omega * t) # 筛选有效数据点:仅保留x≤20的部分参与拟合 valid_mask = x <= 20 x_for_fit = x[valid_mask] y_for_fit = y[valid_mask] # 执行拟合,仅传入有效数据 popt, pcov = curve_fit(damped_sine, x_for_fit, y_for_fit) # 计算各参数的标准差 param_std = np.sqrt(np.diag(pcov)) # 打印拟合结果 print("=== 拟合参数结果 ===") print(f"振幅A: 最优值={popt[0]:.4f}, 标准差={param_std[0]:.4f}") print(f"衰减系数λ: 最优值={popt[1]:.4f}, 标准差={param_std[1]:.4f}") print(f"角频率ω: 最优值={popt[2]:.4f}, 标准差={param_std[2]:.4f}") # 生成全x区间的拟合曲线值(覆盖x>20的噪声段) y_fit_full = damped_sine(x, *popt) # 绘制全区间图像 plt.figure(figsize=(10, 6)) plt.plot(x, y, label="原始实验数据", color="#1f77b4") plt.plot(x, y_fit_full, color="red", linestyle="--", linewidth=2, label="阻尼正弦拟合曲线") plt.axvline(x=20, color="gray", linestyle=":", label="有效数据阈值(x=20)") plt.xlabel("t") plt.ylabel("y(t)") plt.legend() plt.grid(alpha=0.3) plt.show()
小提示:如果后续需要调整有效数据的阈值,只需要修改
valid_mask = x <= 20里的20为对应数值即可,不需要改动其他逻辑。不要用给噪声段数据赋0权重的方式做拟合,直接筛除无效数据的计算效率更高,也完全避免噪声对参数估计的干扰。
内容的提问来源于stack exchange,提问作者IAmOneWithTheScientist
相关产品推荐
相关产品推荐

