Reputation: 32521
How can I vectorize the following double-loop?
I have one N by A matrix and one N by B matrix, where A and B may differ and N is much smaller than A and B. I want to produce an A by B matrix as follows, but ideally without the loops:
import numpy as np
def foo(arr):
# can be anything - just an example so that the code runs
return np.sum(arr)
num_a = 12
num_b = 8
num_dimensions = 3
a = np.random.rand(num_dimensions, num_a)
b = np.random.rand(num_dimensions, num_b)
# this is the loop I want to eliminate:
output = np.zeros( (num_a, num_b) )
for i in xrange(num_a):
for j in xrange(num_b):
output[i,j] = foo(a[:,i] - b[:,j])
Any ideas?
Upvotes: 9
Views: 3087
Reputation: 602305
First vectorise foo()
, i.e. modify foo()
in a way that it can correctly operate on an array of shape (N, A, B)
, returning an array of shape (A, B)
. This step is usually the difficult one. How this is done entirely depends on what foo()
does. For the given example, it's very easy to do:
def foo(arr):
return np.sum(arr, axis=0)
Now, use broadcasting rules to create a (N, A, B)
array containing all the vector differences, and pass it to foo()
:
foo(a[:, :, np.newaxis] - b[:, np.newaxis])
Upvotes: 10