You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

批量光谱文本数据洛伦兹峰拟合:提速与精准获取FWHM

光谱数据洛伦兹峰拟合优化方案

你的代码存在两个核心问题:处理4000个文件速度极慢,以及半高全宽(FWHM)计算不准确。以下是针对性的根源分析、优化方案和完整代码:


问题根源分析

速度慢的核心原因

  • 循环中反复使用pd.concat拼接DataFrame,每次都会创建新对象,时间复杂度呈指数级增长
  • 拟合相关函数采用Python列表逐元素计算,未利用numpy向量化加速
  • 每次拟合都处理全波段数据,未聚焦目标区间(1300-1400)
  • 遍历所有文件时强制绘图,4000次绘图严重拖慢处理速度
  • 使用leastsq效率低于现代优化器,且缺乏参数约束导致收敛慢

FWHM不准确的原因

  • 用固定值generalWidth*2代替拟合得到的真实gamma参数,洛伦兹峰的FWHM本质是2*gamma,必须从拟合结果中提取

优化方案

速度优化措施

  1. 批量读取+并行处理:用joblib实现多进程并行读取和拟合,利用多核CPU资源
  2. 向量化计算:所有数值计算改用numpy数组操作,替代低效的列表推导式
  3. 聚焦目标区间:仅处理1300-1400波数范围的数据,减少计算量
  4. 高效优化器:用scipy.optimize.curve_fit替代leastsq,支持参数约束和快速收敛
  5. 可选绘图:默认关闭批量绘图,仅保留周期性测试绘图开关

准确性优化措施

  1. 正确计算FWHM:从拟合参数中提取gamma值,计算2*gamma作为真实半高全宽
  2. 精准初始参数:针对目标区间先找到峰值位置作为x0初始值,设置合理的gamma和峰高初始值
  3. 参数约束:限制x0在1300-1400区间,gamma和峰高为正数,避免不合理拟合结果

完整优化代码

# -*- coding: utf-8 -*-
import pandas as pd
import glob
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from joblib import Parallel, delayed

# 配置参数
folder_path = 'folder_path'
TARGET_WAVENUMBER_RANGE = (1300, 1400)
PLOT_EVERY_N_FILES = 100  # 每100个文件画一次图,设为None可关闭绘图
N_JOBS = -1  # 使用所有CPU核心

# 批量读取单个光谱文件
def read_spectral_file(file_path):
    df = pd.read_table(file_path, sep="\t")
    # 跳过前67行噪声数据,返回波数列和强度列
    return df.iloc[67:, 0].values, df.iloc[67:, 1].values

# 归一化函数(向量化实现)
def normalize(y):
    y_min = y.min()
    y_max = y.max()
    return (y - y_min) / (y_max - y_min)

# 带基线的洛伦兹峰函数(向量化)
def lorentzian_with_baseline(x, x0, a, gamma, baseline):
    return baseline + a * gamma**2 / (gamma**2 + (x - x0)**2)

# 单峰拟合函数(针对目标区间)
def fit_single_lorentz(x, y):
    # 自动生成初始参数:目标区间内的峰值位置、高度、初始gamma
    peak_idx = np.argmax(y)
    x0_init = x[peak_idx]
    a_init = y[peak_idx] - y.min()
    gamma_init = 10  # 根据实际数据调整初始半高宽
    baseline_init = y.min()
    
    # 参数约束:避免拟合出不合理结果
    bounds = (
        [TARGET_WAVENUMBER_RANGE[0], 0, 1, -np.inf],  # 参数下限
        [TARGET_WAVENUMBER_RANGE[1], np.inf, 50, np.inf]  # 参数上限
    )
    
    try:
        popt, _ = curve_fit(lorentzian_with_baseline, x, y, 
                            p0=[x0_init, a_init, gamma_init, baseline_init],
                            bounds=bounds)
        x0, a, gamma, baseline = popt
        fwhm = 2 * gamma  # 洛伦兹峰FWHM=2*gamma
        return x0, fwhm, a, baseline
    except RuntimeError:
        # 拟合失败时返回NaN标记
        return np.nan, np.nan, np.nan, np.nan

# 处理单个文件的拟合流程
def process_file(idx, x_full, y_raw):
    y_norm = normalize(y_raw)
    # 筛选目标区间的强度数据
    mask = (x_full >= TARGET_WAVENUMBER_RANGE[0]) & (x_full <= TARGET_WAVENUMBER_RANGE[1])
    y_target = y_norm[mask]
    x_target = x_full[mask]
    
    # 执行拟合
    x0, fwhm, a, baseline = fit_single_lorentz(x_target, y_target)
    
    # 周期性绘图(可选)
    if PLOT_EVERY_N_FILES is not None and (idx + 1) % PLOT_EVERY_N_FILES == 0:
        y_fit = lorentzian_with_baseline(x_target, x0, a, fwhm/2, baseline)
        plt.figure(figsize=(8, 4))
        plt.plot(x_target, y_target, label='归一化数据')
        plt.plot(x_target, y_fit, label='洛伦兹拟合')
        plt.xlabel('波数')
        plt.ylabel('归一化强度')
        plt.title(f'文件 {file_list[idx].split("/")[-1]} 拟合结果')
        plt.legend()
        plt.show()
    
    return {
        '文件索引': idx,
        '文件名': file_list[idx].split("/")[-1],
        '主峰位置(x0)': x0,
        'FWHM': fwhm,
        '峰高(a)': a,
        '基线(baseline)': baseline
    }

# 主流程:并行处理所有文件
if __name__ == "__main__":
    file_list = glob.glob(folder_path + "/*.txt")
    # 并行读取所有文件数据
    all_data = Parallel(n_jobs=N_JOBS)(delayed(read_spectral_file)(f) for f in file_list)
    
    # 并行执行拟合
    results = Parallel(n_jobs=N_JOBS)(
        delayed(process_file)(i, x_full, y_raw) for i, (x_full, y_raw) in enumerate(all_data)
    )
    
    # 保存结果到Excel
    results_df = pd.DataFrame(results)
    results_df.to_excel('主峰拟合结果.xlsx', index=False)
    print('拟合完成,结果已保存到 主峰拟合结果.xlsx')

优化说明

  1. 并行处理:多核CPU下速度可提升5-10倍(取决于核心数),4000个文件预计数小时内完成
  2. 向量化计算:将所有循环操作改为numpy数组运算,计算效率提升数十倍
  3. 目标区间聚焦:仅处理1300-1400波数范围,减少无效计算,同时确保只关注目标主峰
  4. 准确FWHM:直接从拟合参数推导真实半高全宽,避免固定值误差
  5. 参数约束:通过边界限制确保拟合结果符合物理意义,提升稳定性

内容的提问来源于stack exchange,提问作者TPoirier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 10:34:51