【发布时间】:2014-02-03 23:10:05
【问题描述】:
我有一个 numpy 脚本,目前运行速度很慢。 大部分时间都在循环中执行以下操作:
terms=zip(Coeff_3,Coeff_2,Curl_x,Curl_y,Curl_z,Ex,Ey,Ez_av)
res=[np.dot(C2,array([C_x,C_y,C_z]))+np.dot(C3,array([ex,ey,ez])) for (C3,C2,C_x,C_y,C_z,ex,ey,ez) in terms]
res=array(res)
Ex[1:Nx-1]=res[1:Nx-1,0]
Ey[1:Nx-1]=res[1:Nx-1,1]
真正减慢代码速度的是列表理解。 在这种情况下,Coeff_3 和 Coeff_2 是长度为 1000 的列表,其元素是 3x3 numpy 矩阵,而 Ex、Ey、Ez、Curl_x 等都是长度为 1000 的 numpy 数组。 我意识到如果我设置单个 3x1000 E 向量之类的操作可能会更快,但是我必须在步骤之间对不同的 E 向量进行大量平均,这会使事情变得非常笨拙。
然而,奇怪的是,我在每个循环中执行两次此操作(一次用于 Ex、Ey,一次用于 Ez),而对 Ez 执行相同的操作几乎需要两倍的时间:
terms2=zip(Coeff_3,Coeff_2,Curl_x,Curl_y,Curl_z,Ex_av,Ey_av,Ez)
res2=array([np.dot(C2,array([C_x,C_y,C_z]))+np.dot(C3,array([ex,ey,ez])) for (C3,C2,C_x,C_y,C_z,ex,ey,ez) in terms2])
有人知道发生了什么吗?如果有什么明显的地方,请原谅我,我对 python 很陌生。
【问题讨论】:
-
你应该把列表理解写成数组操作
-
怎么样?我不太确定该怎么做/
-
如果您可以使用 n 维张量和爱因斯坦求和符号重写此操作,那么在 numpy 中对操作进行向量化将是微不足道的。至少请写出每个对象的尺寸。例如,“Coeff_3”的形状似乎是 (1000,3,3)。
标签: python performance numpy list-comprehension dot-product