Multiplying 2 numpy arrays - python

I have two numpy arrays, the shape of the first array A is (36,) and the second one B is (36, 4). The idea is to multiply corresponding elements like A[0] * B[0] in the way that each of 4 elements of B gets multiplied with corresponding element of A.

You need to add a new axis to A in order to enable broadcasting.
import numpy as np
A = np.random.randint(0, 10, size=(36,4))
B = np.random.randint(0, 10, size=(36,))
A * B.reshape(-1, 1)

Related

How to make (z,x,y,1)-shape numpy array into (z,x,y,3)-shape numpy array by duplicating the last element 3 times?

I want to make (z,x,y,1)-shaped numpy array into (z,x,y,3)-shaped numpy array by duplicating the last element?
For example given
import numpy as np
# The shape is (1,2,2,1) (that is z=1, x=2, y=2)
a = np.array([[[[1], [2]],[[3], [4]]]])
print(a.shape)
# I want to make it (1,2,2,3) by duplicating the last element 3 times as follow
a = np.array([[[[1,1,1], [2,2,2]],[[3,3,3], [4,4,4]]]])
print(a.shape)
so given a numpy array a of shape (z,x,y,1), how to make it (z,x,y,3) numpy array by duplicating the last element?
Try this:
def repeat_last(a, n=3):
a.repeat(n, axis=2).reshape(*a.shape[:-1], n)
You can use np.broadcast_to to do explicit broadcasting.
assert(a.shape[-1] == 1) # check it really is 1 in the last dimension
new_shape = a.shape[:-1] + (3,)
np.broadcast_to(a, new_shape)
You can concatenate three arrays (which are all a) along the last axis:
np.concatenate([a]*3, axis=-1)
NumPy's tile will do the trick. You just have to indicate the number of repetitions of the array along each axis (parameter reps).
In [39]: import numpy as np
In [40]: a = np.array([[[[1], [2]], [[3], [4]]]])
In [41]: b = np.array([[[[1,1,1], [2,2,2]], [[3,3,3], [4,4,4]]]])
In [42]: c = np.tile(a, (1, 1, 1, 3))
In [43]: np.array_equal(b, c)
Out[43]: True

Numpy array with arrays of different size inside

I want to create a 3D np.array named output of varying size. An array of size (5,a,b); with a and b varying (b decreasing):
(a,b) = (1000,20)
(a,b) = (1000,19)
(a,b) = (1000,18)
(a,b) = (1000,17)
(a,b) = (1000,16)
I could create an array of arrays in order to do so, but later on I want to get the first column of all the arrays (without a loop) then I cannot use:
output[:,:,0]
Concatenating them wont work also, it asks for the same size of the arrays...
Any alternatives to be able to have a varying single array instead of an array of arrays?
Thanks!
Like #Divakar said, create an empty array with type object and assign the different sized arrays to their respective indices.
import numpy as np
arrs = [np.ones((5, i, 10 - i)) for i in range(10)]
arrs[0].shape
(5, 0, 10)
arrs[1].shape
(5, 1, 9)
out = np.emtpy(len(arrs), dtype=object)
out[:] = arrs
out[0].shape
(5, 0, 10)
out[1].shape
(5, 1, 9)
Maybe you could make a list and add this 5 arrays.

Scale rows of 3D-tensor

I have an n-by-3-by-3 numpy array A and an n-by-3 numpy array B. I'd now like to multiply every row of every one of the n 3-by-3 matrices with the corresponding scalar in B, i.e.,
import numpy as np
A = np.random.rand(10, 3, 3)
B = np.random.rand(10, 3)
for a, b in zip(A, B):
a = (a.T * b).T
print(a)
Can this be done without the loop as well?
You can use NumPy broadcasting to let the elementwise multiplication happen in a vectorized manner after extending B to 3D after adding a singleton dimension at the end with np.newaxis or its alias/shorthand None. Thus, the implementation would be A*B[:,:,None] or simply A*B[...,None].

compute matrix product for multiple inputs

I am trying to compute a transform given by b = A*x. A is a (3,4) matrix. If x is one (4,1) vector the result is b (3,1).
Instead, for x I have a bunch of vectors concatenated into a matrix and I am trying to evaluate the transform for each value of x. So x is (20, 4). How do I broadcast this in numpy such that I get 20 resulting values for b (20,3)?
I could loop over each input and compute the output but it feels like there must be a better way using broadcasting.
Eg.
A = [[1,0,0,0],
[2,0,0,0],
[3,0,0,0]]
if x is:
x = [[1,1,1,1],
[2,2,2,2]]
b = [[1,2,3],
[2,4,6]]
Each row of x is multiplied with A and result is stored as a row in b.
numpy dot
import numpy as np
A = np.random.normal(size=(3,4))
x = np.random.normal(size=(4,20))
y = np.dot(A,x)
print y.shape
Result: (3, 20)
And of course if you want (20,3) you can use np.transpose()

Python 3d array times 1d vector

I'm trying to multiply a [12x256x256] array with a [12] array. The idea is taht the first one is a stack of 12 [256x256] arrays and the 2nd one is a stack of 1d scalars. So if the 2nd array is [1,2,3,4,...,12], then I want to multiply the first layer of the 3d one by 1, the 2nd layer by 2, etc.
How can I do this?
You can add new axises and multiply them.
import numpy as np
a = np.ones((12,256,256))
b = np.array(range(12))+1
c = a * b[:, np.newaxis, np.newaxis]
In numpy you can do
# let m be 12x256x256, n be 12
m = np.array(m)
n = np.array(n)
(m.swapaxes(0,2) * n).swapaxes(2,0)

Categories