提问人:ttoshiro 提问时间:11/17/2023 最后编辑:ttoshiro 更新时间:11/18/2023 访问量:92
使用 Pandas/NumPy 读取 Excel 文件后,如何将数组数据从对象转换为 float64?
How to cast array data from object to float64 after reading an Excel file with Pandas/NumPy?
问:
我正在尝试在 for 循环中导入多个 Excel 文件,并将文件中的一列转换为 类型的数组,以便稍后在 lmfit 函数中使用。为此,我读取 Excel 文件(由索引迭代),将一列中的数据放入列表中,然后将列表转换为数组。所 示:float64
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:无法将数组数据从 dtype('O') 转换为 dtype('float64') 根据“安全”规则
我看到许多问题(例如,这里、这里、这里)要求解决同一错误,但它们都无法解决这种特定情况,并且尝试在答案中使用建议继续导致错误。例如
我试图在电话中添加一个参数,就像 Adrine Correya 在这里建议的那样,但同样的错误仍然存在。
dtype='float64'
np.array()
我尝试在定义isolated_peak_df后添加该行,并且我还尝试在将isolated_peak定义为列表后添加该行,并在将isolated_peak定义为数组后添加该行,正如 Nick 在下面的评论中建议的那样。但是,在所有情况下,仍然存在相同的错误。
isolated_peak_df = isolated_peak_df.astype('float')
pd.to_numeric(isolated_peak)
此外,正如 MHO 在这里建议的那样,我确保上面显示的数组的大小与执行数学运算的数组的大小相匹配(我还通过制作一个具有相同大小的数组来验证问题出在上面新创建的数组上,从而进行了基本的减法, 而不是后者)。
np.zeros()
而且,正如 xagg 在这里建议和 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)
据我所知,这应该不会引起问题,因为 float64 可以存储介于 2.2E-308 到 1.7E+308 之间的十进制数。所以我不确定为什么 5e15 或 5e20 会引起错误。其余代码如下所示:
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”,只是因为我想测试出了什么问题,所以我选择做一个简单的减法运算,它应该给出一个等于最初导入的数组()的结果(in)——但是,最终,我需要合并两个参数,“x”和“y”。residual
isolated_peak
编辑:完整的错误消息,根据 hpaulj 的请求:
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'
答:
使用以下示例代码: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 相同,但更完整的显示显示显示 dtyperepr
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)
评论
.astype('float')
pd.to_numeric
.can_cast()
返回某些值的内容。你可能会找到作品,但结果很可能是错误的.astype("float64", casting="unsafe")
lmfit
np.array
astype