如何使用numpy数组改善嵌套的for循环

时间:2020-05-16 16:43:33

标签: python arrays numpy nested

我从matlab导入了代码。我想使用numpy数组来避免嵌套循环。但是我失败了,尤其是在最后一部分。摘录来自较大的代码。这部分需要大约5-10分钟的大文件。为简单起见,我减小了循环的大小。

import numpy as np
i = np.sqrt(-1+0j)
omega = np.array([0.0, 392.6, 785.3, 1178.0])
P = np.array([[ 1.,  2.,  3.],
           [ 4.,  5.,  6.],
           [ 7.,  8.,  9.],
           [ 10., 11., 12.]])
cT = np.array([ 100,  600, 1100, 1600, 2100, 2600, 3100])
x = np.array([2.3,2.92,3.55])
c = np.zeros((4,7))
f = np.zeros((4,7))
A = np.zeros((4,7))
for j in range(4):
        for k in range(7): 
            f[j,k] = omega[j]/(2*np.pi)
            c[j,k] = cT[k]
            delta = omega[j]/cT[k]
            temp = 0
            for l in range(3):
                temp = temp + np.exp(-i*delta*x[l])*P[j,l]
            A[j,k] = abs(temp)/3 

我到目前为止所做的:

f = omega/(2*np.pi)+f.T).T
c = cT+c
delta = omega.T/(A+cT).T).T

我无法弄清楚如何在temp和A上实现它,并且我认为有更优雅的方法来获得f和delta。我认为对于temp,我还需要一个像temp.shape =(4,7,3)的维度,然后使用np.sum()对列求和。有人可以帮忙吗?您需要更多信息吗?

2 个答案:

答案 0 :(得分:0)

是的,您可以像这样使用三维尺寸

f = np.zeros((4, 7))
f += omega.reshape(-1, 1) / (2 * np.pi)
c = np.zeros((4, 7))
c += cT
A = (
    np.abs(
        (
            np.exp(
                -i
                * omega.reshape(-1, 1, 1)
                / cT.reshape(1, -1, 1)
                * x.reshape(1, 1, -1)
            )
            * P.reshape(P.shape[0], 1, -1)
        ).sum(axis=2)
    )
    / 3
)

delta = np.divide.outer(omega, cT)

如果需要,它与A分开。

答案 1 :(得分:0)

ipython会话中运行您的代码时,我得到了(对于某些变量):

In [2]: f                                                                                              
Out[2]: 
array([[  0.        ,   0.        ,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ],
       [ 62.48423066,  62.48423066,  62.48423066,  62.48423066,
         62.48423066,  62.48423066,  62.48423066],
       [124.98437681, 124.98437681, 124.98437681, 124.98437681,
        124.98437681, 124.98437681, 124.98437681],
       [187.48452296, 187.48452296, 187.48452296, 187.48452296,
        187.48452296, 187.48452296, 187.48452296]])
In [3]: c                                                                                              
Out[3]: 
array([[ 100.,  600., 1100., 1600., 2100., 2600., 3100.],
       [ 100.,  600., 1100., 1600., 2100., 2600., 3100.],
       [ 100.,  600., 1100., 1600., 2100., 2600., 3100.],
       [ 100.,  600., 1100., 1600., 2100., 2600., 3100.]])
In [4]: A                                                                                              
Out[4]: 
array([[ 2.        ,  2.        ,  2.        ,  2.        ,  2.        ,
         2.        ,  2.        ],
       [ 0.98938405,  4.73223819,  4.91953117,  4.96188066,  4.97785314,
         4.98554628,  4.98983047],
       [ 3.7788147 ,  6.33023676,  7.48300263,  7.75346598,  7.85641105,
         7.9061776 ,  7.93394347],
       [ 7.13085317,  6.16616817,  9.42598136, 10.2410835 , 10.55615294,
        10.70940983, 10.79518136]])

omega有4个值,因此您的f仅将这些值复制到(4,7)数组中。那是故意的吗?

In [5]: omega                                                                                          
Out[5]: array([   0. ,  392.6,  785.3, 1178. ])
In [6]: omega/(2*np.pi)                                                                                
Out[6]: array([  0.        ,  62.48423066, 124.98437681, 187.48452296])

c只是复制到(4,7)数组中的cT的7个值

In [7]: cT                                                                                             
Out[7]: array([ 100,  600, 1100, 1600, 2100, 2600, 3100])

In [9]: cT[None,:].repeat(4,axis=0)                                                                    
Out[9]: 
array([[ 100,  600, 1100, 1600, 2100, 2600, 3100],
       [ 100,  600, 1100, 1600, 2100, 2600, 3100],
       [ 100,  600, 1100, 1600, 2100, 2600, 3100],
       [ 100,  600, 1100, 1600, 2100, 2600, 3100]])

但是您可以使用以下方法从deltaomega制作(4,7)cT

In [64]: delta = omega[:,None]/cT                                                                      
In [65]: delta                                                                                         
Out[65]: 
array([[ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ],
       [ 3.926     ,  0.65433333,  0.35690909,  0.245375  ,  0.18695238,
         0.151     ,  0.12664516],
       [ 7.853     ,  1.30883333,  0.71390909,  0.4908125 ,  0.37395238,
         0.30203846,  0.25332258],
       [11.78      ,  1.96333333,  1.07090909,  0.73625   ,  0.56095238,
         0.45307692,  0.38      ]])

然后,temp只是广播的(4,7,3)乘积,然后是一个和:

In [66]: t = np.sum(np.exp(-i*delta[:,:,None]*x)*P[:,None,:], axis=2)                                  
In [67]: np.allclose(A, abs(t)/3)                                                                      
Out[67]: True

哦,还有次要点

In [68]: i      # i = np.sqrt(-1+0j)                                                                                       
Out[68]: 1j
In [69]: 1j                                                                                            
Out[69]: 1j