numpy.dot as part of a vectorized operation

Viewed 55

Say I have three numpy arrays and I want to perform a calculation over them:

a = np.array([[1,2,3,4,5,6,7],[1,2,3,4,5,6,7],[1,2,3,4,5,6,7],[1,2,3,4,5,6,7], 
[1,2,3,4,5,6,7]]) #shape is (5,7)
b = np.array([[11],[12],[11],[12],[11]]) #shape is (5,1)
c = np.array([[10],[20],[30],[40],[50],[60],[70]]) #shape is (5,1)

The calculation is: 10 + (b(rows) * (c . a(rows)))

  • Where c . a is the dot product of C and the row of a.

  • By rows, I mean doing it as a vector where I need my result to be (7,1) (one row per each column I have on a)

I'm trying to do something like:

result = 10 + (b[:][:] * (np.dot(c.T, a[:]) + b))

But this fails the np.dot operation with shapes being misaligned for that numpy.dot operation. I'm trying to figure out how to perform the calculation above as a one-liner (no for loops) in a way that Python will interpret the vectorized operation, especially for that np.dot part.

Any hints?

Thanks for your time

EDIT: this is a for loop that solves my problem. I'd like to replace that for loop with one Python line.

    iBatchSize = a.shape[0]
    iFeatureCount = a.shape[1]

    result = np.zeros((iBatchSize,1))
    
    for i in range(iBatchSize):
        for j in range(iFeatureCount):
            result [i] = 10 + (b[i][0] * (np.dot(c.T, a[i]) + b))
  • EDIT 2: Corrected array a with the correct array
  • EDIT 3: Corrected expected shape for result
1 Answers
In [31]: a = np.array([[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8]]) #shape is (5,7)
    ...: b = np.array([[11],[12],[11],[12],[11]]) #shape is (5,1)
    ...: c = np.array([[10],[20],[30],[40],[50],[60],[70]]) #shape is (7,1)
In [32]: a.shape, b.shape, c.shape
Out[32]: ((7, 2), (5, 1), (7, 1))

a.shape does not match the comment.

In [33]:     iBatchSize = a.shape[0]
    ...:     iFeatureCount = a.shape[1]
    ...: 
    ...:     result = np.zeros((iBatchSize,1))
    ...: 
    ...:     for i in range(iBatchSize):
    ...:         for j in range(iFeatureCount):
    ...:             result [i] = 10 + (b[i][0] * (np.dot(c.T, a[i]) + b))
    ...: 
Traceback (most recent call last):
  File "<ipython-input-33-717691add3dd>", line 8, in <module>
    result [i] = 10 + (b[i][0] * (np.dot(c.T, a[i]) + b))
  File "<__array_function__ internals>", line 6, in dot
ValueError: shapes (1,7) and (2,) not aligned: 7 (dim 1) != 2 (dim 0)

np.dot is raising that error. It expects the last of first arg to match with the 2nd to the last (or only) of second arg:

In [34]: i
Out[34]: 0
In [35]: c.T.shape
Out[35]: (1, 7)
In [37]: a[i].shape
Out[37]: (2,)

This dot works:

In [38]: np.dot(c.T,a).shape    # (1,7) with (7,2) => (1,2)
Out[38]: (1, 2)

====

With the correct a,

10 + (b[i][0] * (np.dot(c.T, a[i]) + b))

is (5,1) array (because of the +b), which can't be put in result[i].

===

a simple dot of a and c produces a (5,1) which can be combined with b (either with + or * or both), resulting in a (5,1) array:

In [68]: np.dot(a,c).shape
Out[68]: (5, 1)
In [69]: b*(np.dot(a,c)+b)
Out[69]: 
array([[15521],
       [16944],
       [15521],
       [16944],
       [15521]])
Related