【问题标题】:speeding up numpy.dot inside list comprehension在列表理解中加速 numpy.dot
【发布时间】: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


【解决方案1】:

正如前面的 cmets 所指出的,使用数组操作。 np.hstack()np.vstack()np.outer()np.inner() 在这里很有用。您的代码可能会变成这样(不确定您的尺寸):

 Cxyz = np.vstack((Curl_x,Curl_y,Curl_z))
 C2xyz = np.dot(C2, Cxyz)
 ...

检查生成的尺寸的形状,以确保您正确翻译了问题。有时numexpr 也可以显着加快此类任务的速度,而无需付出额外的努力,

【讨论】:

  • 这似乎有效。我已经按照 Option 的建议堆叠了所有向量并使用了爱因斯坦求和,它已经从每秒 15 个周期变为每秒 77 个周期。谢谢!
猜你喜欢
  • 2011-08-24
  • 2023-04-05
  • 2019-11-06
  • 2022-01-05
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
相关资源
最近更新 更多