如何根据分布峰数构建可扩展的高斯拟合优化函数,避免冗余分支
动态多高斯分布拟合实现方案
可以通过可变参数+动态参数拼接的方式实现,完全不需要写多个独立高斯函数和大量分支判断,修正了你原有代码中的复制粘贴错误,完整实现如下:
import numpy as np from scipy.optimize import curve_fit from scipy.signal import find_peaks # 通用多高斯拟合函数,支持任意数量高斯项 def multi_gauss(x, *params): # 第一个参数为全局基线H y = params[0] # 后续每3个参数对应一个高斯的振幅A、均值mean、标准差std for i in range(1, len(params), 3): A, mean, std = params[i], params[i+1], params[i+2] y += A * np.exp(-(x - mean)**2 / (2 * std**2)) return y def get_popt(f, max_peaks=5): x = np.arange(len(f)) # 检测峰位置 means = find_peaks(f, prominence=0.05, width=1)[0] if len(means) == 0: return [] # 限制最大拟合峰数,和你原有逻辑保持一致默认设为5 means = means[:max_peaks] n_peaks = len(means) # 动态生成初始值p0 p0 = [0] # 基线初始值设为0 for m in means: p0.extend([f[m], m, 3]) # 每个峰默认初始值:振幅取峰高、均值取峰位置、标准差取3 # 动态生成参数边界,和你原有设置一致 lower_bounds = [0] upper_bounds = [1] for m in means: lower_bounds.extend([0.9 * f[m], 0.9 * m, 0]) upper_bounds.extend([1.1 * f[m], 1.1 * m, 10]) # 统一调用拟合接口,无需分支判断 popt, _ = curve_fit(multi_gauss, x, f, p0=p0, bounds=(lower_bounds, upper_bounds)) return popt
使用说明
- 拟合返回的
popt参数顺序为:[基线值, 第一个高斯的振幅、均值、标准差, 第二个高斯的振幅、均值、标准差, ...],可直接按顺序拆分使用 - 如果需要提取每个独立高斯的曲线,可参考如下代码:
popt = get_popt(f) x = np.arange(len(f)) H = popt[0] # 存储每个独立高斯曲线的列表 single_gauss_list = [] for i in range(1, len(popt), 3): A, mean, std = popt[i], popt[i+1], popt[i+2] gauss_curve = A * np.exp(-(x - mean)**2 / (2 * std**2)) single_gauss_list.append(gauss_curve) # 总拟合结果 = 基线H + 所有独立高斯曲线的和 total_fit = H + sum(single_gauss_list)
内容的提问来源于stack exchange,提问作者Állan Ferrari
相关产品推荐
相关产品推荐

