1

I am looking for accelerating this loop in numpy but I find no obvious pattern to do so:

for index1 in range(1, len_route):
        time_diff_matrix[index1, (index1+1):len_route] = \
            M[(index1-1):(len_route-2)] - \
            M[index1-1] + \
            N[index1-1, index1:(len_route-1)] + \
            N[index1, (index1+1):len_route] - \
            P[index1:(len_route-1)]

The rest of the time_diff_matrix is populated with zeros. It was a double-loop first. I got rid of one loop but I don't know how to get rid of the other loop. len_route is a large number.

Regards.

4
  • What's the typical value for len_route? Shape of M? Commented Dec 27, 2016 at 13:46
  • can you provide a working minimal example ? Commented Dec 27, 2016 at 13:55
  • len_route is between 300 and 1200. Commented Dec 27, 2016 at 21:53
  • M is a 1-d array with length len_route-1 Commented Dec 27, 2016 at 21:55

1 Answer 1

3

Here's an approach using slicing rows/columns -

n = len_route
vals = M[:n-2] - M[:n-2,None] + N[:n-2,1:n-1] + N[1:n-1,2:n] - P[1:n-1]
r,c = np.triu_indices(len_route-1,1)
time_diff_matrix[r+1,c+1] = vals[r,c-1]

Another approach to avoid using np.triu_indices and using np.triu instead -

time_diff_matrix[1:n-1,2:n] = np.triu(vals)

Verify results -

In [265]: # Setup inputs
     ...: S = 10
     ...: M = np.random.randint(11,99,(S))
     ...: N = np.random.randint(11,99,(S,S))
     ...: P = np.random.randint(11,99,(S))
     ...: time_diff_matrix = np.zeros((S,S), dtype=int)
     ...: len_route = N.shape[0]
     ...: 

In [266]: # Original approach
     ...: for index1 in range(1, len_route):
     ...:     time_diff_matrix[index1, (index1+1):len_route] = \
     ...:         M[(index1-1):(len_route-2)] - \
     ...:         M[index1-1] + \
     ...:         N[index1-1, index1:(len_route-1)] + \
     ...:         N[index1, (index1+1):len_route] - \
     ...:         P[index1:(len_route-1)]
     ...:     

In [267]: # Proposed approach
     ...: time_diff_matrix_out = np.zeros_like(time_diff_matrix)
     ...: n = len_route
     ...: vals = M[:n-2] - M[:n-2,None] + N[:n-2,1:n-1] + N[1:n-1,2:n] - P[1:n-1]
     ...: time_diff_matrix_out[1:n-1,2:n] = np.triu(vals)
     ...: 

In [268]: np.allclose(time_diff_matrix, time_diff_matrix_out)
Out[268]: True
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, it makes a 40% speed improvement. There are twice more calculations but the numpy optimisation overcomes this.
@daguix Consider accepting it if this solved your problem?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.