Python pandas dataframe.value возвращает ndarray со странными свойствами, которые можно построить, но сломать lmfit - PullRequest
0 голосов
/ 05 октября 2018

Я работаю над заданием, которое требует от меня подгонки различных кинетических моделей к некоторым данным концентрации в зависимости от времени.Для этого я выполнил следующие действия:

1. Импортировал электронную таблицу в блокнот Python Jupyter с помощью 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. попытался подогнать модель к данным

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 ​​что-то не так в том, что он возвращает какой-то нечетный пустой массив, который в порядкедля построения, но не подходит для примерки.Кто-нибудь имеет представление о том, в чем разница между этими двумя массивами или как я мог бы исправить ошибку более изящным способом?

РЕДАКТИРОВАТЬ: Вот некоторые дополнительные сведения, которые запрашивали некоторые комментаторы: Вот форма 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.

1 Ответ

0 голосов
/ 07 октября 2018

Это может не полностью ответить на вопрос, но может указать вам правильное направление и в любом случае будет слишком длинным для комментария.

Не зная деталей вашего файла xlsx, он выглядит как ваш коддолжно сработать.Я думаю, что наиболее вероятная подсказка от трассировки - это сообщение "... не является правильным массивом с плавающей точкой".Вы приводите данные и массив x к массивам numpy, но они могут не быть массивами Float64 (двойной точности).

Итак, проверьте тип данных, а также форму и тип ndarrays:

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.

Или это также может бытьМассивы являются «объектными массивами», если в Серии из электронной таблицы смешаны числовые и нечисловые данные.В этом случае вам придется удалить нечисловые строки и / или принудительно установить dtype в Float64.

...