【问题标题】:How to convert numpy.dtype('O') to float?如何将 numpy.dtype('O') 转换为浮点数?
【发布时间】:2020-11-01 10:56:07
【问题描述】:

我正在尝试解决以下一对 ODE:

  • dq/dt = k
  • dk/dt = 1/L (E(t) - R(i) k - 1/C q)

这个想法是求解 q,然后绘制 i(t) = dq/dt。完整代码如下:

import timeit
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

start = timeit.default_timer()

#Data:
t = np.linspace(0, 10, 100)

w1 = 350    #350 rad/s
w2 = 1e3    #1000 rad/s
phi1 = 150  
phi2 = 30

E = np.cos(t)

R1 = 10e3   #10 kOhm
R2 = 3.3e3  #3k3 Ohm

L = 10e-3   #10 mHy
C = 1.56e-6 #1.56 uF

#Create model -> x = [q , k]
def model(x , t):
    
    q = x[0]
    k = x[1]
    
    dq_dt = x[1]
    
    i = dq_dt
    
    R = R1 * i + R2 * i**3
    dk_dt = 1 / L * (E - R * k - 1/C * q)
    
    dx_dt = np.array([dq_dt , dk_dt])
    
    return dx_dt

#Init. cond.:
x0 = np.array([0 , 0])

#Solver ODE:
x = odeint(model, x0, t)

q = x[: , 0]
i = np.diff(q)

vr = (R1 * i + R2 * i**3) * i   
vl = L * np.diff(i)             
vc = 1/C * q                    

#Plot:
plt.style.use("bmh")

fig,(ax1,ax2) = plt.subplots(nrows = 2, ncols = 1, sharex = True)

ax1.plot(t, E, "r-", linewidth = 2)
ax2.plot(t, np.append(i,0), "b-", linewidth = 2)

ax1.grid(True)
ax1.set_title("E(t)")
ax1.set_ylabel("E(t) [V]")

ax2.grid(True)
ax2.set_title("i(t)")
ax2.set_ylabel("i(t) [A]")
ax2.set_xlabel("t [s]")

plt.tight_layout()
plt.show()

end = timeit.default_timer()

print ("\n\n\nSIM TIME = ", end - start, " s")

当我像这样运行代码时,出现以下错误:

  File "...", line 73, in <module>
    x = odeint(model, x0, t)

  File ".../python3.7/site-packages/scipy/integrate/odepack.py", line 244, in odeint
    int(bool(tfirst)))

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

问题在于dx_dt = np.array([dq_dt , dk_dt]) 的返回。由于E 是一个包含100 个元素的数组,dk_dt = dx_dt[1] 也将是一个包含100 个元素的数组,而dq_dt = dx_dt[0] 只是一个值。如果我这样做 dx_dt = np.array([dq_dt , dk_dt] , dtype = float) 我会收到以下错误:

TypeError: only size-1 arrays can be converted to Python scalars

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

  File "...", line 73, in <module>
    x = odeint(model, x0, t)

  File ".../python3.7/site-packages/scipy/integrate/odepack.py", line 244, in odeint
    int(bool(tfirst)))

  File "...", line 65, in model
    dx_dt = np.array([dq_dt , dk_dt] , dtype = float)

ValueError: setting an array element with a sequence.

那么,有没有办法将dx_dt 转换为浮点数,这样它就不会打扰odeint

【问题讨论】:

  • 你想让 "np.array([dq_dt , dk_dt])" 做什么? numpy 将其视为对象数组或错误并不奇怪,因为它是异构的。
  • @Redoubts 因为odeint 需要一个函数来返回导数的表达式,在这种情况下dq dtdx dt
  • model(x0 , t) 产生什么?
  • Numpy 只创建矩形数组。您是否期望 np.array([dq_dt , dk_dt]) 成为 2xN 矩阵?现在它是 L 形的。

标签: python arrays numpy scipy odeint


【解决方案1】:

当我通过x0 定义复制粘贴时:

In [41]: x0                                                                                          
Out[41]: array([0, 0])

并在起点做一个测试计算:

In [42]: model(x0, 0)                                                                                
/usr/local/bin/ipython3:29: VisibleDeprecationWarning: 
Creating an ndarray from ragged nested sequences (which is a 
list-or-tuple of lists-or-tuples-or ndarrays with different 
lengths or shapes) is deprecated. If you meant to do this, you 
must specify 'dtype=object' when creating the ndarray
Out[42]: 
array([0,
       array([100.        ,  99.49028159,  97.9663226 ,  95.44365884,
        91.94800728,  87.51500386,  82.18984026,  76.02680317,
        69.08872084,  61.44632264,  53.17751801,  44.36660217,
        35.10339685,  25.48233457,  15.60149599,   5.56161002,
        -4.53497306, -14.58532495, -24.48698867, -34.139023  ,
       -43.44303157, -52.30416587, -60.63209224, -68.34191273,
       -75.35503059, -81.59995152, -87.01301249, -91.53903077,
       -95.13186646, -97.75489286, -99.38136988, -99.99471662,
       -99.58868039, -98.16740047, -95.74536592, -92.34726785,
       -88.00774772, -82.7710442 , -76.69054217, -69.8282285 ,
       -62.25406016, -54.04525101, -45.28548466, -36.0640614 ,
       -26.47498782, -16.61601846,  -6.58765929,   3.5078569 ,
        13.56761271,  23.48905528,  33.17104177,  42.51487044,
        51.42528687,  59.81145498,  67.58788309,  74.67529543,
        81.00144031,  86.50182667,  91.12038155,  94.81002171,
        97.53313359,  99.26195678,  99.97886703,  99.67655589,
        98.35810522,  96.03695581,  92.73677031,  88.49119201,
        83.34350191,  77.34617746,  70.56035759,  63.05521944,
        54.90727317,  46.19958194,  37.02091515,  27.46484351,
        17.62878515,   7.61301246,  -2.48037008, -12.54846682,
       -22.48863986, -32.19955543, -41.58221687, -50.54097388,
       -58.98449759, -66.8267116 , -73.98766951, -80.39436986,
       -85.9815004 , -90.69210386, -94.47815861, -97.30106822,
       -99.1320549 , -99.95245291, -99.7538988 , -98.53841671,
       -96.31839771, -93.11647348, -88.96528564, -83.90715291])],
      dtype=object)
In [43]: _.shape                                                                                     
Out[43]: (2,)

model 返回一个包含标量 0 的 2 元素对象数组和一个 (100,) 数组。这不是odeint 可以使用的!

【讨论】:

  • 我明白了,我将不得不寻找其他集成商。非常感谢您的回答!
  • dk_dt 部分是 (100,),因为 E 在迭代外部计算为 cos(t) - 这不是迭代内部的 t
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多