微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Scipy 和 Numpy 升级生成“TypeError:无法将数组数据从 dtype('O') 转换为 dtype('float64')”

如何解决Scipy 和 Numpy 升级生成“TypeError:无法将数组数据从 dtype('O') 转换为 dtype('float64')”

我正在将代码从 Python 2.7 转换为 Python 3.8。

在 Python 2.7 版本中,我不得不使用 scipy 和 numpy 的降级版本以避免 TypeError(见下文)。使用 Python 3.8,这些降级版本的 scipy 和 numpy 不再可用,我收到此错误,无法修复。

1.设置

一个:MacOS Catalina 10.15.7、Python 2.7.16、numpy 1.9.0、scipy 1.0.1

新:MacOS Catalina 10.15.7、Python 3.8.6、numpy 1.20.3、scipy 1.4.0

2.代码

调用 scipy.integrate.odeint 时发生:

y_trajectory = scipy.integrate.odeint(growth_a_derivs,y_start,t_array,atol=eps,args=myargs)

使用 growth_a_derivs 函数y_start,t_array numpy 数组,dtype float64eps 浮点数和 myargs 包含字典的长度为 1 的元组

3.错误

弹出以下回溯:

Traceback (most recent call last):
  
  <long blah blah blah>

  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyxcosmo/icosmo_cosmo.py",line 149,in growth_a
    result=growth_a_ode(cosmo,a,unnorm=unnorm)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyxcosmo/icosmo_cosmo.py",line 671,in growth_a_ode
    y_trajectory = scipy.integrate.odeint(growth_a_derivs,args=myargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/scipy/integrate/odepack.py",line 242,in odeint
    output = _odepack.odeint(func,y0,t,args,Dfun,col_deriv,ml,mu,TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

所以最后一行是在 scipy 的集成 pckg 中,对 odeint 的完整调用是:

    output = _odepack.odeint(func,full_output,rtol,atol,tcrit,h0,hmax,hmin,ixpr,mxstep,mxhnil,mxordn,mxords,int(bool(tfirst)))

在这里面,错误一个编译的 scipy .so 文件中,因此我无法进一步分析这个错误。我只知道对growth_a_derivs 的调用没有问题(它的print() 调用所有工作)。但我不知道这是一个 numpy 还是 scipy 问题,以及如何克服它。

4.分辨率!

多亏了下面的@RFoxtea 回答,我才能够理解这个问题。 我相信这个问题是由 numpy 版本的变化引起的。 growth_a_derivs输出是:

np.array([f1,f2])

与:

type(f1) = numpy.float64
type(f2) = numpy.ndarray
f2.shape = (1,)

使用 numpy 1.9,这给出:

np.array([f1,f2]) = [1.234,np.array([1.234])]
np.array([f1,f2]).dtype = numpy.float64

使用 numpy 1.20,这给出:

np.array([f1,f2]).dtype = numpy.object

这不被scipy.integrate.odeint接受。 但是,请注意 scipy.integrate.solve_ivp 可以。

感谢您的帮助!

解决方法

在运行 scipy.integrate.odeint 的某个时刻,Numpy 被告知将 Python 对象数组转换为浮点数数组,它回答您说它不能这样做。您的描述表明问题必须与 y_startt_start 或(也许,我不确定)growth_a_derivs 的返回值有关。请确保这些都具有可以转换为浮点数的适当 dtype。可能很容易修复。

,

感谢@RFoxtea 提供了正确的解决方案。

然而,还有一个有趣的选择。您可以使用 scipy.integrate.solve_ivp 而不是 scipy.integrate.odeint

Solve_ivp 可以处理带有 dtype funobject 输出。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。