如何用Polyfit拟合不含峰值的特定区域多项式?
针对无峰值区域的线性拟合解决方案
问题根源排查
你之前的操作没消除峰值影响,大概率是峰值检测不彻底或者删除峰值后仍残留峰值相关数据,毕竟直接删峰值索引很难精准保留目标平坦区域。下面给你几个更可靠的步骤:
1. 先确认峰值检测是否准确
scipy.find_peaks的默认参数不一定适配你的数据,先可视化验证检测结果:
import matplotlib.pyplot as plt from scipy.signal import find_peaks # 假设已去除NaN的原始x、y数据 peaks, peak_info = find_peaks(y, height=0.3, distance=8) # 按需调height(峰值最小高度)、distance(相邻峰值最小间距) plt.plot(x, y, label="原始数据") plt.plot(x[peaks], y[peaks], "rx", label="检测到的峰值") plt.legend() plt.show()
如果图里黄色区域外的峰值没被标红,就调整height和distance参数,直到所有需要排除的峰值都被识别。
2. 直接筛选无峰值的目标区域(最靠谱的方法)
与其删除峰值,不如直接圈出黄色标注的无峰值区域:
- 如果黄色区域是x的固定区间(比如x在10到50之间):
# 生成筛选掩码 mask = (x > 10) & (x < 50) # 替换成你的实际区间 x_clean = x[mask] y_clean = y[mask] - 如果黄色区域是峰值之间的平坦段(位置不固定):
先检测峰值和谷值,再取相邻峰谷之间的区域:# 检测峰值和谷值 peaks, _ = find_peaks(y, height=0.3) valleys, _ = find_peaks(-y, height=-0.3) # 取y的负数来检测谷值 # 假设黄色区域是第一个峰值到第一个谷值之间的区域,按需调整索引 mask = (x > x[peaks[0]]) & (x < x[valleys[0]]) x_clean = x[mask] y_clean = y[mask]
3. 用清洁后的数据集拟合
确保用筛选后的x_clean和y_clean做拟合,而不是原始删峰值的数据:
import numpy as np # 计算log(x),注意x_clean不能有0或负数,否则先做处理 log_x_clean = np.log(x_clean) # 一阶线性拟合(y = a*log(x) + b) coeffs = np.polyfit(log_x_clean, y_clean, 1) a, b = coeffs # 生成拟合曲线并验证 y_fit = a * log_x_clean + b plt.plot(log_x_clean, y_clean, "o", label="无峰值区域数据") plt.plot(log_x_clean, y_fit, "-", label=f"拟合线: y={a:.2f}log(x)+{b:.2f}") plt.legend() plt.show()
4. 验证拟合效果
如果拟合结果还是和含峰值的没差异,检查这几点:
- 筛选后的
x_clean和y_clean绘图确认是否真的无峰值 - 检查
log_x_clean是否有NaN(x不能为0或负数,若有则先剔除这些点) - 确认拟合的是
log(x)和y的关系,而不是其他变量组合
内容的提问来源于stack exchange,提问作者LuLuK
相关产品推荐
相关产品推荐

