如何在使用Pandas/NumPy阅读Excel文件后将数组数据从对象转换为float 64?

bmvo0sr5  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(111)

我尝试在for循环中导入一些Excel文件,并将文件中的列转换为float64类型的数组,以便稍后在lmfit函数中使用。为此,我读取Excel文件(通过索引迭代),将一列中的数据放入列表中,然后将列表转换为数组。如下所示:

isolated_peak_df = pd.read_excel(path + r'/Residuals_{}.xlsx'.format(i), header=None)
isolated_peak = [a for a in isolated_peak_df.transpose().iloc[0].loc[0:50]]
isolated_340_peak = np.array(isolated_340_peak)

字符串
这也适用于其他目的,但是当我试图使用新创建的数组在lmfit函数中进行一些数学运算时,我得到了错误:
TypeError:无法根据规则“safe”将数组数据从dtype(“O”)转换为dtype(“float 64”)
我已经看到了许多问题(例如,hereherehere)要求解决同一个错误,但没有一个解决这个特定的情况,并试图在答案中使用建议继续导致错误。例如,

  • 我尝试将dtype='float64'作为参数添加到np.array()调用中,就像Adrine Correya建议的here一样,但仍然存在相同的错误。
  • 我尝试在定义isolated_peak_df后的行中添加isolated_peak_df = isolated_peak_df.astype('float'),并且我还尝试在定义isolated_peak为列表后的行和定义isolated_peak为数组后的行中添加pd.to_numeric(isolated_peak),正如Nick在下面的评论中所建议的那样。然而,在所有情况下,仍然存在相同的错误。
  • 此外,正如MHO建议的here,我确保上面显示的数组的大小与正在执行数学运算的数组的大小相匹配(我还做了一个基本的减法,制作了一个大小相同的np.zeros()数组,以验证问题是上面新创建的数组,而不是后者)。
  • 而且,正如xagg建议的here和hpaulj在下面的注解中建议的那样,我确保传递的所有值确实是浮点数,而不是字符串或其他非数字数据。

提供的其他答案是特定于scipy/sci-kit而不是lmfit的。

**编辑:**我现在怀疑错误与数组的数据类型无关,因为错误会暗示,但在我在lmfit函数中使用的参数的大小中。通过将“x”和“y”参数的起始值减少几个数量级(例如,减少到5),错误不再出现。

freeParams = Parameters()
freeParams.add("x", value = 5 * (10 ** 20), vary=True)
freeParams.add("y", value = 5 * (10 ** 15), vary=True)


据我所知,这应该不会引起问题,因为float 64可以存储范围在2.2E-308到1.7E+308之间的十进制数。所以我不确定为什么5e 15或5e 20会引起错误。剩下的代码如下所示:

epsfcn=0.01
ftol=1.e-10
xtol=1.e-10
max_nfev=300

for i in absorption.index:
    isolated_peak_df = pd.read_excel(path + r'/Residuals_{}.xlsx'.format(i), header=None)
    isolated_peak = [a for a in isolated_peak_df.transpose().iloc[0].loc[0:50]]
    isolated_peak = np.array(isolated_peak)
    
    def calc_residual(freeParams, isolated_peak):
        residual = isolated_peak[5:22] - np.zeros(17)
        return residual

    mini = minimize(calc_residual, freeParams, args=(isolated_peak,), epsfcn=epsfcn, ftol=ftol, xtol=xtol, max_nfev=max_nfev, calc_covar=True, nan_policy="omit")


请注意,在上面的代码中没有使用“x”和“y”,只是因为我想测试出了什么问题,所以我选择执行一个简单的减法运算,该运算应该给出一个等于最初导入的数组(isolated_peak)的结果(在residual中)--然而,最终我需要合并两个参数“x”和“y”。
Edit:Full error message,per hpaulj's request:

TypeError                                 Traceback (most recent call last)
Cell In[202], line 19
     16     residual = isolated_peak[5:22] - np.zeros(17)
     17     return residual
---> 19 mini = minimize(calc_residual, freeParams, args=(isolated_peak,), epsfcn=epsfcn, ftol=ftol, xtol=xtol, max_nfev=max_nfev, calc_covar=True, nan_policy="omit")

File ~/opt/anaconda3/lib/python3.9/site-packages/lmfit/minimizer.py:2600, in minimize(fcn, params, method, args, kws, iter_cb, scale_covar, nan_policy, reduce_fcn, calc_covar, max_nfev, **fit_kws)
   2460 """Perform the minimization of the objective function.
   2461 
   2462 The minimize function takes an objective function to be minimized,
   (...)
   2594 
   2595 """
   2596 fitter = Minimizer(fcn, params, fcn_args=args, fcn_kws=kws,
   2597                    iter_cb=iter_cb, scale_covar=scale_covar,
   2598                    nan_policy=nan_policy, reduce_fcn=reduce_fcn,
   2599                    calc_covar=calc_covar, max_nfev=max_nfev, **fit_kws)
-> 2600 return fitter.minimize(method=method)

File ~/opt/anaconda3/lib/python3.9/site-packages/lmfit/minimizer.py:2369, in Minimizer.minimize(self, method, params, **kws)
   2366         if (key.lower().startswith(user_method) or
   2367                 val.lower().startswith(user_method)):
   2368             kwargs['method'] = val
-> 2369 return function(**kwargs)

File ~/opt/anaconda3/lib/python3.9/site-packages/lmfit/minimizer.py:1693, in Minimizer.leastsq(self, params, max_nfev, **kws)
   1691 result.call_kws = lskws
   1692 try:
-> 1693     lsout = scipy_leastsq(self.__residual, variables, **lskws)
   1694 except AbortFitException:
   1695     pass

File ~/opt/anaconda3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:426, in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
    424     if maxfev == 0:
    425         maxfev = 200*(n + 1)
--> 426     retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
    427                              gtol, maxfev, epsfcn, factor, diag)
    428 else:
    429     if col_deriv:

TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

zf2sa74q

zf2sa74q1#

使用scipy.leastsq的示例代码:

In [122]: from scipy.optimize import leastsq
     ...: def func(x):
     ...:     return 2*(x-3)**2+1
     ...: leastsq(func, 0)
Out[122]: (array([2.99999999]), 1)

字符串
提供一个数字数组:

In [124]: leastsq(func, np.array([1,2,3]))
Out[124]: (array([1., 2., 3.]), 2)


但是如果我把它变成一个对象dtype数组,我会得到一个很像lmfit的错误:

In [125]: leastsq(func, np.array([1,2,3]).astype(object))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[125], line 1
----> 1 leastsq(func, np.array([1,2,3]).astype(object))

File ~\miniconda3\lib\site-packages\scipy\optimize\_minpack_py.py:426, in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
    424     if maxfev == 0:
    425         maxfev = 200*(n + 1)
--> 426     retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
    427                              gtol, maxfev, epsfcn, factor, diag)
    428 else:
    429     if col_deriv:

TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'


对象dtype数组的打印可能看起来与数字dtype相同,但更完整的repr显示显示的是dtype

In [127]: print(np.array([1,2,3]).astype(object))
[1 2 3]

In [128]: np.array([1,2,3]).astype(object)
Out[128]: array([1, 2, 3], dtype=object)

相关问题