Python3: vectorizing nested loops

会有一股神秘感。 提交于 2020-01-24 20:43:06

问题


I have this function:

def fun(x):   # x is a vector with size: (size_x*size_y) = n 
    c = 0
    f_vec = np.zeros((size_x*size_y))


    for i in range(size_x):
        for j in range(size_y):
             f_vec[c]=i*j*x[c]   
             c=c+1

    return f_vec

I do this because what happens is that the vector x is (considering size_x=4 and size_y=3)

 x[0]=x00    #c=0  i=0,j=0
 x[1]=x01    #c=1  i=0, j=1
 x[2]=x02    #c=2   i=0. j=size_y-1
 x[3]=x10    #c=3   i=1, j=0
 x[4]=x11
  ...
 x[n]=x32    #c=n   i=size_x-1, j= size_y-1

Can I avoid the nested loop and do a simple vector operation? I would like to have something like f[c] = F[x[c]] *i *j

But it is not that simple to find i and j by knowing the c value. Do you know a way?

Thanks.


回答1:


You can use broadcasting for this:

(
    x.reshape(size_x, size_y) *
    np.arange(size_x)[:, None] *
    np.arange(size_y)
).ravel()

or Einstein Summation form

np.einsum(
    'ij,i,j->ij',
    x.reshape(size_x, size_y),
    np.arange(size_x),
    np.arange(size_y)
).ravel()



回答2:


Essentially, this is the same as Nils Werner's answer, but I find it easier to understand the i*j part as the 2D ndarray np.outer(np.arange(x_size), np.arange(y_size), and then do broadcasting:

(x.reshape(x_size, y_size) * np.outer(np.arange(x_size), np.arange(y_size)).ravel()

You can pre-calculate the i*j part if you're doing this repeatedly for the same values of x_size and y_size.



来源:https://stackoverflow.com/questions/59270410/python3-vectorizing-nested-loops

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!