Reputation: 176
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
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
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