Aakash Lakshmanan
Aakash Lakshmanan

Reputation: 176

Does anyone see any possible way to slice this? (python)

I've been trying to speed up some numpy arrays in Python and I know for loops are really bad so you should slice them but I just can't see anyway to slice this. Maybe there's some smart trick? I am pretty inexperienced in this so would appreciate any help!

    def propind(in1, in2):
        return in1+M*in2
     
    for ind1 in range(M):
        for ind2 in range(N):
            for ind3 in range(M):
                for ind4 in range(N):
                    ret[propind(ind1,ind2), propind(ind3,ind4)] = tempH0s[ind1,ind2,ind4]*(ind1==ind3)

tempH0s is a MxNxN matrix and ret is a (MxN)x(MxN) matrix.

Upvotes: 0

Views: 71

Answers (2)

hpaulj
hpaulj

Reputation: 231738

I was trying something like

ret = np.zeros((M,N,M,N))
ind = np.arange(M)
ret[ind,:,ind,:] = tempH0s[ind,:,:]
ret = ret.reshape(M*N, M*N)

but the layout of values was different from what your iteration does. I suspect that in1+M*in2 mapping is part of the difference.

If the difference can be worked out, this should be quite a bit faster.

In [93]: tempH0s                                                                                     
Out[93]: 
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]]])

your iteration produces

In [87]: foo(tempH0s,2,3)                                                                            
Out[87]: 
array([[ 0,  1,  0,  0,  0,  0],
       [ 3,  4,  0,  0,  0,  0],
       [ 0,  0,  9, 10, 11,  0],
       [ 0,  0, 12, 13, 14,  0],
       [ 0,  0, 15, 16, 17,  0],
       [ 0,  0,  0,  0,  0,  0]])

where as my suggestion produces:

array([[ 0,  1,  2,  0,  0,  0],
       [ 3,  4,  5,  0,  0,  0],
       [ 6,  7,  8,  0,  0,  0],
       [ 0,  0,  0,  9, 10, 11],
       [ 0,  0,  0, 12, 13, 14],
       [ 0,  0,  0, 15, 16, 17]])

Your other code produces

array([[ 0.,  0.,  1.,  0.,  2.,  0.],
       [ 0.,  9.,  0., 10.,  0., 11.],
       [ 3.,  0.,  4.,  0.,  5.,  0.],
       [ 0., 12.,  0., 13.,  0., 14.],
       [ 6.,  0.,  7.,  0.,  8.,  0.],
       [ 0., 15.,  0., 16.,  0., 17.]])

Upvotes: 1

Aakash Lakshmanan
Aakash Lakshmanan

Reputation: 176

Just wanted to give the solution I got using the comments to this question. It is about 20 times faster so thank you!

tempH0s2 = []

for z in range(M):
    tempL = np.zeros([M,N,N])
    tempL[z] = 1
    tempH0s2.append(tempH0s*tempL)

tempH0s3 = np.stack(tempH0s2, axis=2)

ret = np.reshape(tempH0s3, (M*N, M*N), order='F')

Upvotes: 1

Related Questions