Python 如何在Numpy中对这个双for循环进行矢量化?
我有一些Python/Numpy代码运行缓慢,我认为这是因为使用了双for循环。这是代码Python 如何在Numpy中对这个双for循环进行矢量化?,python,numpy,vectorization,Python,Numpy,Vectorization,我有一些Python/Numpy代码运行缓慢,我认为这是因为使用了双for循环。这是代码 def heat(D,u0,q,tdim): xdim = np.size(u0) Z = np.zeros([xdim,tdim]) Z[:,0]=u0; for i in range(1,tdim): for j in range (1,xdim-1): Z[j,i]=Z[j,i-1]+D*q*(Z[j-1,i-1]-2*Z[j,i
def heat(D,u0,q,tdim):
xdim = np.size(u0)
Z = np.zeros([xdim,tdim])
Z[:,0]=u0;
for i in range(1,tdim):
for j in range (1,xdim-1):
Z[j,i]=Z[j,i-1]+D*q*(Z[j-1,i-1]-2*Z[j,i-1]+Z[j+1,i-1])
return Z
我正在尝试删除双for循环并将Z矢量化。以下是我的尝试
def heat(D,u0,q,tdim):
xdim = np.size(u0)
Z = np.zeros([xdim,tdim])
Z[:,0]=u0;
Z[1:,1:-1]=Z[1:-1,:-1]+D*q*(Z[:-2,:-1]-2*Z[1:-1,:-1]+Z[2:,:-1])
return Z
这不起作用-我得到以下错误:
operands could not be broadcast together with shapes (24,73) (23,74)
所以在尝试矢量化Z时,我搞砸了。你能帮我找出我的错误吗 您无法在问题的时间维度中对扩散计算进行矢量化,这仍然需要一个循环。这里唯一明显的优化是用调用
numpy.diff
函数(预编译为C)替换拉普拉斯计算,因此热方程解算器变为:
def heat(D,u0,q,tdim):
xdim = np.size(u0)
Z = np.zeros([xdim,tdim])
Z[:,0]=u0;
for i in range(1,tdim):
Z[1:-1,i]=Z[1:-1,i-1] + D*q*np.diff(Z[:,i-1], 2)
return Z
对于非平凡的空间大小,您应该会看到相当快的速度 您将无法删除这两个for循环,因为计算列i依赖于列i-1(在您的第二位代码中),除了第一列之外,列i-1仅为零 你能做的是:
def heat(D,u0,q,tdim):
xdim = np.size(u0)
Z = np.zeros([xdim,tdim])
Z[:,0]=u0;
for i in range(1,tdim):
Z[1:-1,i] = Z[1:-1,i-1] + D*q*(Z[:-2,i-1] - 2*Z[1:-1,i-1] + Z[2:,i-1])
return Z
要返回代码,请执行以下操作:
您正在用(仅第一学期)Z[1:-1,:-1]填充Z[1,1:-1]。形状上的不匹配在这里很明显
忽略第二个索引(因为您无论如何都必须循环),您的矢量化解决方案使用与非矢量化方法不同的假设:在第一个版本中,您有一面u0(Z[:,0])和两面0(Z[0,:]和Z[-1,:]),而在矢量化解决方案中,您尝试通过填充Z[1:,i]将Z[-1,:]设置为除0以外的其他值。你想模拟哪种情况 当我遇到这种错误时,我总是试图打印出或多或少的所有内容的
len
。检查Z[1:,1:-1]
的长度是否正确,依此类推。是否尝试使用cProfile或其他工具分析代码?我认为你应该首先确定你真正的瓶颈。瓶颈是对heat的调用,它占用了99.9%的程序时间。是的,这就是我需要优化的地方,我已经读到矢量化将大大加快我的代码。在维度上我只差1:/@user1493692,很抱歉,直接优化并不是那么简单(毕竟)。for循环依赖于以前更改的值(是否需要?),如果像这样进行矢量化,则不会发生这种情况,在进行更大的攻击之前,如果您不介意小的编译步骤,则更容易使用cython…我尝试将其用作指南,其中它们矢量化了一个看起来非常类似于我的double for循环。在我的原始代码中,D*q*np.diff(Z[:,i-1],2)
实际上代替了什么。用diff
计算的第二个差值替换了Z[j-1,i-1]-2*Z[j,i-1]+Z[j+1,i-1])
。尽管表面上有相似之处,但你提到的博客文章并不像你的博客文章那样对循环进行矢量化。