Python - 根据记录的值拟合指数衰减曲线

4
我知道这方面有相关的讨论帖子,但是我不确定我应该将我的数据拟合到哪里。我的数据被导入并绘制如下。
import matplotlib.pyplot as plt
%matplotlib inline
import pylab as plb
import numpy as np
import scipy as sp
import csv

FreqTime1 = []
DecayCount1 = []
with open('Half_Life.csv', 'r') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader:
        FreqTime1.append(row[0])
        DecayCount1.append(row[3])

FreqTime1 = np.array(FreqTime1) 
DecayCount1 = np.array(DecayCount1)

fig1 = plt.figure(figsize=(15,6))
ax1 = fig1.add_subplot(111)
ax1.plot(FreqTime1,DecayCount1, ".", label = 'Run 1')
ax1.set_xlabel('Time (sec)')
ax1.set_ylabel('Count')
plt.legend()

enter image description here

问题是,我在设置一般的指数衰减方面遇到了困难,我不确定如何从数据集中计算参数值。
如果可能的话,我还希望将拟合的衰减方程式与图形一起显示。但是,如果能够产生合适的拟合,则可以轻松应用此功能。
编辑-------------------------------------------------------------
因此,在使用Stanely R提到的拟合函数时
def model_func(x, a, k, b):
    return a * np.exp(-k*x) + b

x = FreqTime1
y = DecayCount1


p0 = (1.,1.e-5,1.) 
opt, pcov = curve_fit(model_func, x, y, p0)
a, k, b = opt

我遇到了这个错误信息:

TypeError: 函数 'multiply' 没有匹配类型为 dtype('S32') dtype('S32') dtype('S32') 的循环

你有什么解决办法吗?


请查看以下网址:https://dev59.com/SWEi5IYBdhLWcg3wRauf - Warren Weckesser
2个回答

7

您需要使用scipy.optimize中的curve_fit函数:http://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.optimize.curve_fit.html

from scipy.optimize import curve_fit
import numpy as np
# define type of function to search
def model_func(x, a, k, b):
    return a * np.exp(-k*x) + b

# sample data
x = np.array([399.75, 989.25, 1578.75, 2168.25, 2757.75, 3347.25, 3936.75, 4526.25, 5115.75, 5705.25])
y = np.array([109,62,39,13,10,4,2,0,1,2])

# curve fit
p0 = (1.,1.e-5,1.) # starting search koefs
opt, pcov = curve_fit(model_func, x, y, p0)
a, k, b = opt
# test result
x2 = np.linspace(250, 6000, 250)
y2 = model_func(x2, a, k, b)
fig, ax = plt.subplots()
ax.plot(x2, y2, color='r', label='Fit. func: $f(x) = %.3f e^{%.3f x} %+.3f$' % (a,k,b))
ax.plot(x, y, 'bo', label='data with noise')
ax.legend(loc='best')
plt.show()

enter image description here


好的。对于这种情况,我是否需要为我的数据集应用for循环? - iron2man
循环是为了什么?curve_fit已经搜索到了合适的拟合函数。 - Serenity
当我将我的 x 和 y 值定义为数组时,返回的错误信息是:ufunc 'multiply' did not contain a loop with signature matching types dtype('S32') dtype('S32') dtype('S32') - iron2man
1
尝试编写以下代码:FreqTime1.append(np.float32(row[0])); DecayCount1.append(np.float32(row[3])) - Serenity
很好。在绘图时,我们需要在指数中加入一个负号: label='拟合函数:$f(x) = %.3f e^{-%.3f x} %+.3f$' % (a,k,b)) - undefined

1
我收到了这个错误信息。
TypeError: ufunc 'multiply' did not contain a loop with signature matching types dtype('S32') dtype('S32') dtype('S32')

你有解决这个问题的任何想法吗?

读取CSV文件以创建FreqTime1DelayCount1的代码正在创建字符串数组。您可以通过遵循@StanleyR在评论中提出的建议来解决该问题。更好的方法是替换此代码:

FreqTime1 = []
DecayCount1 = []
with open('Half_Life.csv', 'r') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader:
        FreqTime1.append(row[0])
        DecayCount1.append(row[3])

FreqTime1 = np.array(FreqTime1) 
DecayCount1 = np.array(DecayCount1)

使用:

FreqTime1, DecayCount1 = np.loadtxt('Half_Life.csv', delimiter=',', usecols=(0, 3), unpack=True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接