【发布时间】:2016-04-14 14:00:15
【问题描述】:
我有一小段代码来自一个更大的脚本。我发现当函数t_area 被调用时,它负责大部分的运行时间。我自己测试了这个功能,它并不慢,我相信它需要运行很多次,所以需要很多时间。下面是调用函数的代码:
tri_area = np.zeros((numx,numy),dtype=float)
for jj in range(0,numy-1):
for ii in range(0,numx-1):
xp = x[ii,jj]
yp = y[ii,jj]
zp = surface[ii,jj]
ap = np.array((xp,yp,zp))
xp = xp+dx
zp = surface[ii+1,jj]
bp = np.array((xp,yp,zp))
yp = yp+dx
zp = surface[ii+1,jj+1]
dp = np.array((xp,yp,zp))
xp = xp-dx
zp = surface[ii,jj+1]
cp = np.array((xp,yp,zp))
tri_area[ii,jj] = t_area(ap,bp,cp,dp)
这里使用的数组大小为216 x 217,x 和y 的值也是如此。我对 python 编码很陌生,我过去使用过 MATLAB。所以我的问题是,有没有办法绕过这两个 for 循环,或者有一种更有效的方法来运行这段代码?寻求任何帮助加快这一进程!谢谢!
编辑:
感谢大家的帮助,这解决了很多困惑。我被问到循环中使用的函数 t_area,下面是代码:
def t_area(a,b,c,d):
ab=b-a
ac=c-a
tri_area_a = 0.5*linalg.norm(np.cross(ab,ac))
db=b-d
dc=c-d
tri_area_d = 0.5*linalg.norm(np.cross(db,dc))
ba=a-b
bd=d-b
tri_area_b = 0.5*linalg.norm(np.cross(ba,bd))
ca=a-c
cd=d-c
tri_area_c = 0.5*linalg.norm(np.cross(ca,cd))
av_area = (tri_area_a + tri_area_b + tri_area_c + tri_area_d)*0.5
return(av_area)
对不起,符号混乱,当时它是有道理的,现在回头看我可能会改变它。谢谢!
【问题讨论】:
-
至少,您不必在每次迭代中分配新数组。
-
您可以通过将
ap,bp,cp,dp存储在数组中并重写t_area以迭代这些数组来保存〜40000 次函数调用。此外,也许您可以不使用np.array来仅存储 3 个值。 -
你能告诉我们函数
t_area()发生了什么吗?是矢量化的吗? -
好消息是您的函数可以完全向量化。我已经编辑了我的答案以考虑到这一点。我已经对措辞进行了一些调整,以便将问题向量化放在首位。否则,没有添加太多。
-
非常感谢!你让我对python结构有了更好的理解!我在完整脚本中还有其他几个地方,这个实现将非常有用!与最终计算的数据相比,现在输入到此脚本中的数据很小。我之前提到的这个数组大小来自一个 ~ 2mb 的文本文件,而稍后来自文本文件的数据将是 ~ 1.5-2 gb!所以这肯定会加快速度!
标签: python performance for-loop vectorization micro-optimization