如何对pandas.DataFrame列的直方图进行高斯拟合并计算FWHM?
完整实现方案
你需要提前安装依赖库:pandas numpy matplotlib scipy,以下是可直接运行的代码:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit # 示例构造DataFrame,你有现成数据的话直接替换这部分即可 data = {"ABC": [-40,-30,-30,-20,-20,-10,-10,-10,0,0,0,0,10,10,10,10,20,20,20,30,40]} df = pd.DataFrame(data) # 1. 绘制直方图,同时提取直方图数据用于后续拟合 # bins参数可根据数据粒度调整,density=True做归一化,不需要可以改成False counts, bin_edges, patches = plt.hist(df["ABC"], bins="auto", density=True, alpha=0.6, label="原始数据直方图") # 计算bin中点作为拟合的x输入 bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2 # 2. 高斯拟合 # 定义高斯函数 def gaussian(x, amp, mu, sigma): return amp * np.exp(-(x - mu)**2 / (2 * sigma**2)) # 初始参数猜测:振幅取直方图最大值,均值取数据均值,标准差取数据标准差,保证拟合快速收敛 init_params = [np.max(counts), np.mean(df["ABC"]), np.std(df["ABC"])] # 执行拟合 popt, _ = curve_fit(gaussian, bin_centers, counts, p0=init_params) fit_amp, fit_mu, fit_sigma = popt # 绘制拟合曲线 x_fit = np.linspace(df["ABC"].min(), df["ABC"].max(), 1000) y_fit = gaussian(x_fit, *popt) plt.plot(x_fit, y_fit, "r--", linewidth=2, label=f"高斯拟合曲线\nμ={fit_mu:.2f}, σ={fit_sigma:.2f}") # 3. 计算半高全宽FWHM,直接用高斯分布解析公式:FWHM = 2*√(2ln2)*σ ≈ 2.3548*σ fwhm = 2 * np.sqrt(2 * np.log(2)) * fit_sigma print(f"拟合得到的半高全宽FWHM为:{fwhm:.2f}") # 图表格式配置 plt.xlabel("ABC取值") plt.ylabel("频率密度") plt.legend() plt.show()
注意事项
- 如果拟合不收敛,可以手动调整
init_params的三个初始值,一般用数据本身的均值和标准差作为初始值就足够适配绝大多数场景 - 不需要密度归一化的话,把
plt.hist的density参数改为False即可,拟合逻辑会自动适配计数数据
内容的提问来源于stack exchange,提问作者김수환김수환
相关产品推荐
相关产品推荐

