Home > Software design >  How to vectorize performing pairwise sums given two numpy arrays?
How to vectorize performing pairwise sums given two numpy arrays?

Time:11-13

I have two numpy arrays which look like this:

x = [v1, v2, v3, ..., vm]
y = [w1, w2, w3, ..., wn]

where vi, wj are numpy arrays of length 3.

I want to perform a pairwise summation of v's and w's and get a final array

z = [v1 w1, v1 w2,...,v1 wn,v2 w1, ..., vi wj, ..., vm wn]

A simple way of obtaining z is as follows:

z = np.zeros ((m*n, 3))
for i in range(m):
    for j in range(n):
        z[m*i j] = x[i]   y[j] 

This computation is not feasible is m, n are very large.

I know scipy.spatial has methods to enumerate pairwise distances using distance_matrix in a vectorized fashion.

I want to ask if there is a vectorized version of performing such pairwise additions for numpy arrays?

CodePudding user response:

You can take advantage of broadcasting, creating a 2D array, then you can easily get z[i,j] = x[i] y[j]

x = np.reshape(x, (-1, 1)) # shape (N, 1)
y = np.reshape(y, (-1, 1)) # shape (N, 1)
z = x   y.T # shape (N, N)

If you want to have z as a 1D array you can do z.reshape(-1).

CodePudding user response:

If x is mx3 matrix, y is a nx3

x.shape # (m,3)
y.shape # (n,3)

x1 = x.reshape(m,1,3)      
y1 = y.reshape(1,n,3)
z = x1   y1     # shape (m,n,3)
z1 = z.reshape(-1,3)   # (m*n, 3)

equivalently

 z = x[:,None] y

test:

In [263]: x=np.arange(12).reshape(4,3); y=np.arange(6).reshape(2,3)    
In [264]: z = x[:,None] y    
In [265]: z.shape
Out[265]: (4, 2, 3)
    
In [266]: z
Out[266]: 
array([[[ 0,  2,  4],
        [ 3,  5,  7]],

       [[ 3,  5,  7],
        [ 6,  8, 10]],

       [[ 6,  8, 10],
        [ 9, 11, 13]],

       [[ 9, 11, 13],
        [12, 14, 16]]])
  • Related