Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.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中带数组索引的嵌套循环_Python_Numpy - Fatal编程技术网

Python numpy中带数组索引的嵌套循环

Python numpy中带数组索引的嵌套循环,python,numpy,Python,Numpy,我想知道如何做到以下几点: def GetFlux(self, time): bx = self.GetField("bx", time) * self.wpewce by = self.GetField("by", time) * self.wpewce bz = self.GetField("bz", time) * self.wpewce flux = np.zeros((self.ncells[0]+1,self.ncell

我想知道如何做到以下几点:

def GetFlux(self, time):
    bx = self.GetField("bx", time) * self.wpewce
    by = self.GetField("by", time) * self.wpewce
    bz = self.GetField("bz", time) * self.wpewce              

    flux  = np.zeros((self.ncells[0]+1,self.ncells[1]+1),"float32", order='FORTRAN')
    flux2  = np.zeros((self.ncells[0]+1,self.ncells[1]+1),"float32", order='FORTRAN')

    dx = self.dl[0]
    dz = self.dl[1]

    nx = self.ncells[0]
    nz = self.ncells[1]

    j = 0

    for i in np.arange(1, nx):
        flux2[i,0] = flux2[i-1,0] + bz[i-1,0]*dx
    flux[1:,0] = flux[0,0] + np.cumsum(bz[:-1,0]*dx)

    for j in np.arange(1,nz):
        flux2[0,j] = flux2[0,j-1] - bx[0,j-1]*dz
    flux[0,1:] = flux[0,0] - np.cumsum(bx[0,:-1]*dz)

    for i in np.arange(1,nx):
        for j in np.arange(1,nz):
            flux2[i,j] = 0.5*(flux2[i-1,j] + bz[i-1,j]*dx) + 0.5*(flux2[i,j-1] - bx[i,j-1]*dz)

    return flux2 
但是没有两个嵌套循环,这需要很长时间
Bx
Bz
flux
是相同大小的数组

我已经设法用数组索引和cumsum替换了前两个单循环,但是我找不到如何替换嵌套循环

有什么想法吗


多亏了内部循环的矢量化相当简单。您有一个基本方程,如下所示:

X[n] = a * X[n-1] + b[n]
for i in np.arange(1,nx+1):
    for j in np.arange(1,nz+1):
        flux2[i,j] = 0.5*(flux2[i-1,j] + bz[i-1,j]*dx) \
                   + 0.5*(flux2[i,j-1] - bx[i,j-1]*dz)
a = 0.5
aexp = np.arange(nz).reshape(nz, 1) - np.arange(nz).reshape(1, nz)
abcoeff = a**aexp
abcoeff[aexp<0] = 0
for i in np.arange(1,nx+1):
    b = 0.5*flux2[i-1, 1:] + 0.5*bz[i-1, 1:]*dx - 0.5*bx[i,:-1]*dz
    bvals = (abcoeff * b.reshape(1, nz)).sum(axis=1)
    n = np.arange(1, nz+1)
    x0 = flux2[i, 0]
    flux2[i, 1:] = a**n * x0 + bvals
这个方程可以展开和重写,而不依赖于X[n-1]:

X[n] = a^n * X[0] + a^(n-1) * b[0] + a^(n-2) * b[1] + ... + a^0 * b[n]
如果原始代码是这样的:

X[n] = a * X[n-1] + b[n]
for i in np.arange(1,nx+1):
    for j in np.arange(1,nz+1):
        flux2[i,j] = 0.5*(flux2[i-1,j] + bz[i-1,j]*dx) \
                   + 0.5*(flux2[i,j-1] - bx[i,j-1]*dz)
a = 0.5
aexp = np.arange(nz).reshape(nz, 1) - np.arange(nz).reshape(1, nz)
abcoeff = a**aexp
abcoeff[aexp<0] = 0
for i in np.arange(1,nx+1):
    b = 0.5*flux2[i-1, 1:] + 0.5*bz[i-1, 1:]*dx - 0.5*bx[i,:-1]*dz
    bvals = (abcoeff * b.reshape(1, nz)).sum(axis=1)
    n = np.arange(1, nz+1)
    x0 = flux2[i, 0]
    flux2[i, 1:] = a**n * x0 + bvals
您可以像这样消除内部循环:

X[n] = a * X[n-1] + b[n]
for i in np.arange(1,nx+1):
    for j in np.arange(1,nz+1):
        flux2[i,j] = 0.5*(flux2[i-1,j] + bz[i-1,j]*dx) \
                   + 0.5*(flux2[i,j-1] - bx[i,j-1]*dz)
a = 0.5
aexp = np.arange(nz).reshape(nz, 1) - np.arange(nz).reshape(1, nz)
abcoeff = a**aexp
abcoeff[aexp<0] = 0
for i in np.arange(1,nx+1):
    b = 0.5*flux2[i-1, 1:] + 0.5*bz[i-1, 1:]*dx - 0.5*bx[i,:-1]*dz
    bvals = (abcoeff * b.reshape(1, nz)).sum(axis=1)
    n = np.arange(1, nz+1)
    x0 = flux2[i, 0]
    flux2[i, 1:] = a**n * x0 + bvals
a=0.5
aexp=np.arange(新西兰)。重塑(新西兰,1)-np.arange(新西兰)。重塑(新西兰,1)
abcoeff=a**aexp
abcoeff[aexp有可能(ab)使用scipy.ndimage.convalve来解决此类问题。可能在scipy中使用一些过滤方法也会起作用,而且会更好,因为它不依赖于scipy.ndimage.convalve工作(我可以想象在遥远的将来会发生这种变化)。(编辑:首先编写scipy.signal.convolve,它与numpy.convolve类似,无法执行此操作)

诀窍在于此卷积函数可以就地使用,因此双for循环:

for i in xrange(1, flux.shape[0]):
    for j in xrange(1, flux.shape[1]):
        flux[i,j] = 0.5*(flux[i-1,j] + bz[i-1,j]*dx) + 0.5*(flux[i,j-1] - bx[i,j-1]*dz)
可以替换为(抱歉,需要这么多临时阵列…):

不幸的是,这意味着我们需要区分bx,bz如何进入最终结果,但这种方法避免了产生二次幂,并且应该比前面的答案快得多


(请注意,numpy convolve函数不允许这种就地使用。)

使用convolve的方法非常好,但模具的制作方式并不明显。。。 如果这条线

flux[i,j] = 0.5*(flux[i-1,j] + bz[i-1,j]*dx) + 0.5*(flux[i,j-1] - bx[i,j-1]*dz)
被替换为

flux[i,j] = a*flux[i-1,j] + b*bz[i-1,j] + c*flux[i,j-1] - d*bx[i,j-1]

我认为第一个卷积(在x通量上)将使用模板[[0,a],[b,0 ] ],但是对于bz和bx的其他2个模板,假设a、b、c和d是标量,

是否意味着在最内环中使用j?并且考虑使用<代码> xLangle(n)< /C> >而不是<代码> NP.Arang.(n)
。后者创建了一个数组,并浪费了您似乎没有使用的内存。前者只是一个迭代器。此外,您的代码可能格式错误,因为存在三重嵌套的for循环,而没有单循环。抱歉,尼诺;更好的代码在这里:我可以替换前两个单循环;但不能替换最后两个嵌套的循环(第33-35行)。