我正在逐步从Matlab转向Python,并希望得到一些优化迭代循环的建议。 这就是我当前正在运行循环的方式,对于信息,我已经包含了定义变量的代码。
nh = 2000
h = np.array(range(nh))
nt = 10000
wmin = 1
wmax = 10
hw = np.array(wmin + (wmax-wmin)*invlogit(randn(1,nh)));
sl = np.array(zeros((nh,1))+radians(40))
fa = np.array(zeros((nh,1))+radians(35))
c = np.array(zeros((nh,1))+4.4)
y = np.array(zeros((nh,1))+17.6)
yw = np.array(zeros((nh,1))+9.81)
ir = 0.028
m = np.array(zeros((nh,nt)));
m[:,49] = 0.1
z = np.array(zeros((nh,nt)))
z[:,0] = 0+(3.0773-0)*rand(nh,1).T
reset = np.array(zeros((nh,nt)))
fs = np.array(zeros((nh,nt)))
for t in xrange(0, nt-1):
fs[:,t] = (c.T+(y.T-m[:,t]*yw.T)*z[:,t]*(np.cos(sl.T)**2)*np.tan(fa.T))/(y.T*z[:,t]*np.sin(sl.T)*np.cos(sl.T))
reset[fs[:,t]<=1,t+1] = 1;
z[fs[:,t]<=1,t+1] = 0;
z[fs[:,t]>1,t+1] = z[fs[:,t]>1,t]+(ir/hw[0,fs[:,t]>1]).T
这就是我在Matlab中优化代码的方法,但它在python中的运行速度相当慢。我怀疑有更多的pythonic方法可以做到这一点,我真的很欣赏正确方向的推动。 非常感谢!
答案 0 :(得分:0)
不是特别关于循环,你在看起来像这样的调用中做了大量的额外工作:
np.array(zeros((nh,nt)))
只需使用:
np.zeros((nh,nt))
取而代之的是。此外,您可以替换:
h = np.array(range(nh))
使用:
h = np.arange(nh)
其他评论:
np.sin(sl.T)*np.cos(sl.T)
,但sl
似乎根本没有变化。只计算一次并将其分配给您在循环中使用的变量。你可以通过一系列的三次调用来实现这一目标。答案 1 :(得分:0)
表达式
(c.T+(y.T-m[:,t]*yw.T)*z[:,t]*(np.cos(sl.T)**2)*np.tan(fa.T))/(y.T*z[:,t]*np.sin(sl.T)*np.cos(sl.T))
使用在循环内不会更改的c, y, m, yw, sl, fa
。您可以在循环之前计算几个子表达式。
此外,大多数数组都包含一个重复值。您可以使用标量进行计算:
sl = radians(40)
fa = radians(35)
c = 4.4
y = 17.6
yw = 9.81
然后,使用预先计算的子表达式:
A = cos(sl)**2 * tan(fa) * (y - m*yw)
B = y*sin(sl)*cos(sl)
for t in xrange(0, nt-1):
fs[:,t] = (c + A[:,t]*z[:,t]) / (B*z[:,t])
less = fs[:,t]<=1
more = np.logical_not(less)
reset[less,t+1] = 1
z[less,t+1] = 0
z[more,t+1] = z[more,t]+(ir/hw[0,more]).T