我有一个从excel导出的数组A
,包含如图所示的数据值。第一列x
和第二列y
是因变量,而第三列z
是独立变量(输出)。
from xlrd import open_workbook
Data = open_workbook("simple.xls")
sheet = Data.sheet_by_name('Sheet1')
A=[]
# Read row by row
for rownum in range(sheet.nrows):
rowValues = sheet.row_values(rownum)
A.append(rowValues)
A = np.array(A)
A=
[[ 0.00000000e+00 1.49761692e-05 0.00000000e+00]
[ 8.85000000e+02 1.49761692e-05 6.41362500e-02]
[ 1.48500000e+03 1.49761692e-05 1.19340000e-01]
[ 2.09000000e+03 1.49761692e-05 1.58760000e-01]
[ 3.36000000e+03 1.49761692e-05 2.08080000e-01]
[ 3.87000000e+03 1.49761692e-05 2.16933750e-01]
[ 6.48000000e+03 1.49761692e-05 2.46746250e-01]
[ 8.22000000e+03 1.49761692e-05 2.54700000e-01]
[ 1.05300000e+04 1.49761692e-05 2.59470000e-01]
[ 1.58250000e+04 1.49761692e-05 2.62035000e-01]
[ 2.37600000e+04 1.49761692e-05 2.68751250e-01]
[ 8.18400000e+04 1.49761692e-05 2.92848750e-01]
[ 0.00000000e+00 8.57250668e-06 0.00000000e+00]
[ 6.75000000e+02 8.57250668e-06 4.97436412e-02]
[ 1.27500000e+03 8.57250668e-06 1.27749375e-01]
[ 1.88000000e+03 8.57250668e-06 1.88617039e-01]
[ 3.15000000e+03 8.57250668e-06 2.65089780e-01]
[ 3.66000000e+03 8.57250668e-06 2.90344849e-01]
[ 6.27000000e+03 8.57250668e-06 3.36295316e-01]
[ 8.01000000e+03 8.57250668e-06 3.42702439e-01]
[ 1.03200000e+04 8.57250668e-06 3.65205982e-01]
[ 1.56150000e+04 8.57250668e-06 3.67269626e-01]
[ 2.35500000e+04 8.57250668e-06 3.87296798e-01]
[ 8.16300000e+04 8.57250668e-06 4.43486869e-01]
[ 0.00000000e+00 4.26671486e-06 0.00000000e+00]
[ 4.65000000e+02 4.26671486e-06 2.61407250e-02]
[ 1.06500000e+03 4.26671486e-06 1.22371762e-01]
[ 1.67000000e+03 4.26671486e-06 2.19629475e-01]
[ 2.94000000e+03 4.26671486e-06 3.26680087e-01]
[ 3.45000000e+03 4.26671486e-06 3.34340662e-01]
[ 6.06000000e+03 4.26671486e-06 4.18330575e-01]
[ 7.80000000e+03 4.26671486e-06 4.50631350e-01]
[ 1.01100000e+04 4.26671486e-06 4.55053950e-01]
[ 1.54050000e+04 4.26671486e-06 4.60937587e-01]
[ 2.33400000e+04 4.26671486e-06 5.10770813e-01]
[ 8.14200000e+04 4.26671486e-06 6.12569587e-01]
[ 0.00000000e+00 2.13335743e-06 0.00000000e+00]
[ 8.55000000e+02 2.13335743e-06 1.03773150e-01]
[ 1.46000000e+03 2.13335743e-06 2.21130000e-01]
[ 2.73000000e+03 2.13335743e-06 3.45515625e-01]
[ 3.24000000e+03 2.13335743e-06 3.85634925e-01]
[ 5.85000000e+03 2.13335743e-06 4.76061300e-01]
[ 7.59000000e+03 2.13335743e-06 4.79220300e-01]
[ 1.51950000e+04 2.13335743e-06 5.24709900e-01]
[ 2.31300000e+04 2.13335743e-06 5.64829200e-01]
[ 8.12100000e+04 2.13335743e-06 6.46568325e-01]
[ 0.00000000e+00 1.42359023e-06 0.00000000e+00]
[ 6.45000000e+02 1.42359023e-06 8.03596500e-02]
[ 1.25000000e+03 1.42359023e-06 2.36700000e-01]
[ 2.52000000e+03 1.42359023e-06 4.25941650e-01]
[ 3.03000000e+03 1.42359023e-06 4.61683350e-01]
[ 5.64000000e+03 1.42359023e-06 5.99561100e-01]
[ 7.38000000e+03 1.42359023e-06 6.05952000e-01]
[ 9.69000000e+03 1.42359023e-06 6.16958550e-01]
[ 1.49850000e+04 1.42359023e-06 6.57434250e-01]
[ 2.29200000e+04 1.42359023e-06 6.45954300e-01]
[ 8.10000000e+04 1.42359023e-06 7.79689800e-01]
[ 0.00000000e+00 9.36010573e-07 0.00000000e+00]
[ 4.35000000e+02 9.36010573e-07 3.40200000e-02]
[ 1.04000000e+03 9.36010573e-07 1.91160000e-01]
[ 2.31000000e+03 9.36010573e-07 3.77640000e-01]
[ 2.82000000e+03 9.36010573e-07 4.44240000e-01]
[ 5.43000000e+03 9.36010573e-07 5.50440000e-01]
[ 7.17000000e+03 9.36010573e-07 5.36580000e-01]
[ 9.48000000e+03 9.36010573e-07 5.83740000e-01]
[ 1.47750000e+04 9.36010573e-07 5.87340000e-01]
[ 2.27100000e+04 9.36010573e-07 6.33060000e-01]
[ 8.07900000e+04 9.36010573e-07 7.36200000e-01]]
x= A[:,0]
y= A[:,1]
z= A[:,2]
我有一个适合数组A数据的函数,以求解系数a
和b
。
def func(data,a,b):
return a/(data[:,1]*b)*np.log(1+(data[:,1]*b/a)*(1-np.exp(-a*data[:,0])))
其余代码显示系数a
和b
,scipy.optimize.curve_fit()
函数和matplotlib.pyplot
的初始猜测,以绘制结果。
guess = [3.0e-5, 128 ]
print guess, 'initial guessed parameters'
params, pcov = scipy.optimize.curve_fit(func, A[:,:2], A[:,2], guess)
print params, 'fitted parameters'
import matplotlib.pyplot as plt
plt.plot(x,func(A,params[0],params[1]),'-r',x,z,'o')
plt.title('Plot')
plt.legend(['Fit', 'Data'], loc='lower right')
plt.show()
情节的结果是这个
结果系数为:
[3e-05, 128] initial guessed parameters
[ 2.00773153e-04 1.22752179e+02] fitted parameters
因为所有数据都在array
A中,scipy
认为数组中的点从一个点连接到另一个点,导致每个曲线的末尾返回到原点,这是也是后续曲线的开始。
我应该如何在python
中编码,以便scipy.optimize.curve_fit
知道数组中的数据由多条曲线组成,而不是一条单一的联合数据?任何建议都将不胜感激。
答案 0 :(得分:0)
我已经编辑了代码(后面附带),你只是将它的剪切和粘贴复制到Python中,以防其他人想要尝试。
但是,我不确定我理解你的问题。看起来x
和y
是您的独立(非依赖)变量,z
是您的因变量(即,从每个(x,y)
对计算出来的东西)。在这种情况下,我认为你想要一个三维的情节 - 目前,如果我正确地阅读这个,你正在绘制z
vs {{1}并且没有显示x
。
假设你确实想要这样做,我同意这些评论,如果你将单独的曲线分开,它会是最好的 - 我认为归零会对你的拟合产生负面影响。您可以使用y
查找np.where(A[:,0]==0)[0]
的索引,并在循环中将其用于拆分A - 尽管我认为x==0
会在一行中为您执行此操作。
np.split(A,np.where(A[:,0]==0)[0])
答案 1 :(得分:0)
您的数据集A
似乎背靠背包含所有这些曲线。
相反,您可以每次A[:,0] == 0.00000000e+00
拆分数据集。将它分成6个数据集后,您可以分别适合每个数据集。
但如果我正确理解您的问题,您还希望每个数据集的参数a
和b
都相同,对吗?
为了帮助您实现这一目标,我将无耻地插入我的symfit
包,其中包含curve_fit
以使这些问题更容易解决。
在symfit
中,您可以执行以下操作::
from symfit import Fit, variables, parameters, log, exp
datasets = [A_1, A_2, ...] # I'm going to assume this holds the untangled datasets one through six
xs = variables('x_1, x_2, x_3, x_4, x_5, x_6')
ys = variables('y_1, y_2, y_3, y_4, y_5, y_6')
zs = variables('z_1, ...') # same for z
a, b = parameters('a, b')
model_dict = {
z: a/(y * b) * log(1 + (y * b/a) * (1 - exp(- a * x)))
for x, y, z in zip(xs, ys, zs)
}
此代码将创建一个矢量值模型,该模型允许您同时适应此方程组(每个中都有a
和b
的相同实例!)。为了适应,我们现在可以简单地执行以下操作:
fit = Fit(model_dict,
x_1=datasets[0][:,0], x_2=datasets[1][:,0], ...,
y_1=datasets[0][:,1], y_2=datasets[1][:,1], ...,
z_1=datasets[0][:,2], z_2=datasets[1][:,2], ...
)
我没有完整地写出所有内容,但我希望这能让你知道如何完成这一切。可以在文档中找到更多信息:symfit docs。
作为最后的评论,请注意我使用了符号exp和log,而不是numpy。