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

Python拟合指数衰减函数得到直线的问题排查

问题:拟合指数衰减函数却得到直线

我用Python对数据进行最优拟合,尝试拟合指数衰减函数,但结果却得到一条直线。数据存储在GitHub仓库DeAngelo-neutrino/artie的pythonprogram文件夹中,可忽略其中图片。

核心代码流程如下:

  1. 导入库并读取数据
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd 
import os
import math
import sys
from scipy.interpolate import UnivariateSpline
from scipy.optimize import curve_fit  # 原代码遗漏该关键导入

np.set_printoptions(threshold=sys.maxsize)
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

os.chdir("/Users/dwooley/Desktop/Python_programs/")

# 读取数据列
time_argon = np.genfromtxt("log_all_chan_5_10-14_17_44.txt",skip_header=9, delimiter=",", usecols=(0))   
target_top = np.genfromtxt("log_all_chan_5_10-14_17_44.txt",skip_header=9, delimiter=",", usecols=(1))   
target_side = np.genfromtxt("log_all_chan_5_10-14_17_44.txt",skip_header=9, delimiter=",", usecols=(2))   
target_bottom = np.genfromtxt("log_all_chan_5_10-14_17_44.txt",skip_header=9, delimiter=",", usecols=(3))   
front_plate= np.genfromtxt("log_all_chan_5_10-14_17_44.txt",skip_header=9, delimiter=",", usecols=(4))  
N2_level= np.genfromtxt("log_all_chan_5_10-14_17_44.txt",skip_header=9, delimiter=",", usecols=(9))   
  1. 创建DataFrame并计算滚动平均
df = pd.read_csv("log_all_chan_5_10-14_17_44.txt", skiprows=9, sep=',' )

window_size = 900
time_column = df['Time (s)']
N2_level_dataseries = df['N2 Level']
N2_average = N2_level_dataseries.rolling(window = window_size).mean()
  1. 体积计算(省略无关细节)
# 此处为体积计算代码,略去具体实现
# ...
df['volume(Argon)'] = v_h_0+(df['test']) + twice_length*full_integration
volume_function_as_height = df['volume(Argon)']
  1. 筛选数据并拟合
lower_parsed_data = 8000
upper_parsed_data = 10000

data_we_use = volume_function_as_height.iloc[lower_parsed_data:upper_parsed_data]
# 补充原代码缺失的时间数据切片
parsed_time_average = time_column.iloc[lower_parsed_data:upper_parsed_data]

def exponential_decay(x, A, B, C):
    return A* np.exp(-B * x) + C

x_data = parsed_time_average  
y_data = data_we_use 

initial_guess = [max(y_data), 1, min(y_data)]

# 执行拟合
popt, pcov = curve_fit(exponential_decay, x_data, y_data, p0=initial_guess)

A_opt, B_opt, C_opt = popt
y_fit = exponential_decay(x_data, *popt)

# 绘图
plt.figure(figsize=(10, 6))
plt.plot(x_data, y_data, 'g-',label='数据')
plt.plot(x_data, y_fit, label='指数衰减拟合', color='blue')
plt.xlabel('时间(s)')
plt.ylabel('氩气体积(inches³)')
plt.title('指数衰减拟合结果')
plt.legend()
plt.show()

拟合结果为直线而非预期曲线,以下是解决思路:

  • 修正初始猜测值:初始猜测的B值设为1过大(时间以秒为单位时,衰减常数通常很小),建议改为贴合数据量级的数值,比如:

    initial_guess = [max(y_data)-min(y_data), 0.0001, min(y_data)]
    
  • 确保x与y数据完全匹配:原代码未定义parsed_time_average,必须补充时间数据的切片代码,保证时间序列和体积序列的索引完全对应,否则拟合逻辑会失效。

  • 添加拟合参数边界:强制B为正数(避免B=0导致直线拟合),在curve_fit中加入边界限制:

    popt, pcov = curve_fit(exponential_decay, x_data, y_data, p0=initial_guess, bounds=([0, 1e-6, 0], [np.inf, np.inf, np.inf]))
    
  • 检查滚动平均的影响:窗口大小900可能过度平滑数据,掩盖了衰减趋势。尝试减小窗口(如100)或直接使用原始N2_level_dataseries计算,观察数据的真实变化趋势。

  • 验证数据区间:当前选择的8000-10000行数据可能已处于衰减末期,接近平稳状态,自然呈现线性。可以尝试选择更早的区间(如3000-7000行),看是否存在明显的衰减特征。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:05:52