Python pandas dataframe.value returns 具有奇怪属性的 ndarray,可以绘制但会破坏 lmfit

Python pandas dataframe.value returns a ndarray with strange properties, that can be plotted but break lmfit

我正在做一项作业,要求我将不同的动力学模型拟合到一些浓度与时间数据。为了完成这个,我执行了以下步骤:

1.Imported 将电子表格放入 python Jupyter notebook pandas.read_excel,然后删除第 20 行后的所有列

data = pd.read_excel("assignment1.xlsx")[:21]

2.plotted部分数据

X = data["X"].values
t = np.linspace(0,20,len(X))
plt.figure(1)
plt.plot(t,X)
plt.xlabel("time")
plt.ylabel("Conversion(x)")

3.attempted 使模型适合数据

from lmfit import minimize, Parameters, Model, Parameter

X2 = data["X"].values
t2 = np.linspace(0,20.1,len(X))
y2 = (data["A"].values+data["B"].values)*X
y3 = []
t3 = []


for y in y2: #these are used a little later 
    y3.append(y)
for t in t2:
    t3.append(t)


def test2(t,k):
    return t*k 

aModel = Model(test2)

p = aModel.make_params()
p["k"] = Parameter(name="k",value=3,min=0)



result = aModel.fit(np.array(y2),params=p,t=np.array(t2)) #source of error

但我收到以下错误...

error: Result from function call is not a proper array of floats.

但是下面的代码连同前一个块减去结果行并没有给我一个错误

result = aModel.fit(np.array(y3),params=p,t=np.array(t3)) #y3, t3 replaces t2, y2

显然 df.values 有问题,因为它 returns 一些奇怪的 numpy 数组,可以用于绘图但不能用于拟合。有谁知道这两个数组之间有什么区别,或者我如何才能以更优雅的方式修复错误?

编辑: 以下是一些评论者要求的一些额外信息: 这是 t2、y2 的形状和类型 代码:

print("t2 shape: ", t2.shape, "t2 type: ", type(t2))
print("y2 shape: ", y2.shape, "y2 type: ", type(y2))

输出:

t2 shape:  (21,) t2 type:  <class 'numpy.ndarray'>
y2 shape:  (21,) y2 type:  <class 'numpy.ndarray'>

完整追溯:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-312-0681483eeeeb> in <module>()
     28 
     29 
---> 30 result = aModel.fit(np.array(y2),params=p,t=np.array(t2))
     31 
     32 print(test2([0,3,0,3,0],1))

~\Anaconda3\lib\site-packages\lmfit\model.py in fit(self, data, params, weights, method, iter_cb, scale_covar, verbose, fit_kws, nan_policy, **kwargs)
    871                              scale_covar=scale_covar, fcn_kws=kwargs,
    872                              nan_policy=self.nan_policy, **fit_kws)
--> 873         output.fit(data=data, weights=weights)
    874         output.components = self.components
    875         return output

~\Anaconda3\lib\site-packages\lmfit\model.py in fit(self, data, params, weights, method, nan_policy, **kwargs)
   1215         self.userkws.update(kwargs)
   1216         self.init_fit = self.model.eval(params=self.params, **self.userkws)
-> 1217         _ret = self.minimize(method=self.method)
   1218 
   1219         for attr in dir(_ret):

~\Anaconda3\lib\site-packages\lmfit\minimizer.py in minimize(self, method, params, **kws)
   1809                         val.lower().startswith(user_method)):
   1810                     kwargs['method'] = val
-> 1811         return function(**kwargs)
   1812 
   1813 

~\Anaconda3\lib\site-packages\lmfit\minimizer.py in leastsq(self, params, **kws)
   1362 
   1363         try:
-> 1364             lsout = scipy_leastsq(self.__residual, variables, **lskws)
   1365             _best, _cov, infodict, errmsg, ier = lsout
   1366             result.residual = infodict['fvec']

~\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
    392         with _MINPACK_LOCK:
    393             retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 394                                      gtol, maxfev, epsfcn, factor, diag)
    395     else:
    396         if col_deriv:

error: Result from function call is not a proper array of floats.

这可能无法完全回答问题,但可能会为您指明正确的方向,而且对于评论来说太长了。

在不知道 xlsx 文件的详细信息的情况下,看起来您的代码应该可以工作。我认为回溯中最有可能的线索是消息“...不是正确的浮点数组”。您将数据和 x 数组强制为 numpy 数组,但它们可能不是 Float64(双精度)数组。

因此检查数据类型以及 ndarray 的形状和类型:

print("t2 shape: ", t2.shape, "t2 type: ", type(t2), "t2 dtype: ", t2.dtype)

为了适合工作,这必须是 dtype('float64')

如果电子表格中的值都是整数,则数组可能是整数数组。在那种情况下,只需

t2 = np.array(t2, dtype='float64')

t2 = np.asfarray(t2)

等等强制数组为 Float64。

或者,如果电子表格中的系列混合了数值数据和非数值数据,数组也可能是 "object arrays"。在这种情况下,您必须删除非数字行,and/or 强制 dtype 为 Float64。