Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Numpy中对这个双for循环进行矢量化?_Python_Numpy_Vectorization - Fatal编程技术网

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

我有一些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-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])
。尽管表面上有相似之处,但你提到的博客文章并不像你的博客文章那样对循环进行矢量化。