multiply multidimensional arrays in python - python

I have stored a number of 2d arrays in a 3d array and I need to multiply each one with a vector. so I have stored all those vectors in a 2d array. It's like this:
A = np.random.random((L, M, N))
B = np.random.random((L, M))
and I need to multiply each A[l] by B[l] which results in a Nx1 array and the output of the whole operation would be a LxN 2d array. Is there a function that can do this or do I need a loop?

An option is np.einsum
import numpy as np
output = np.einsum("ijk, ij -> ik", A, B)
This results in a (L, N) sized array containing matrix products of all the A[i].T.dot(B[i])

Related

nested operations on two numpy arrays, one 2d and one 1d

Say I have one 2d numpy array X with shape (3,3) and one numpy array Y with shape (3,) where
X = np.array([[0,1,2],
[3,4,5],
[1,9,2]])
Y = np.array([[1,0,1]])
How can I create a numpy array, Z for example, from multiplying X,Y element-wise and then summation row-wise?
multiplying element-wise would yield: 0,0,2, 3,0,5, 1,0,2
then, adding each row would yield:
Z = np.array([2,8,3])
I have tried variations of
Z = np.sum(X * Y) --> adds all elements of entire array, not row-wise.
I know I can use a forloop but the dataset is very large and so I am trying to find a more efficient numpy-specific way to perform the operation. Is this possible?
You can do the following:
sum_row = np.sum(X*Y, axis=1) # axis=0 for columnwise

Most efficient way to apply operation on each element of Numpy array

Assume I have a function which takes a numpy array of shape (m, k) and I want to apply that function on each element of numpy array of shape (n, m, k).
Naive approach is to iterate through the given numpy array and append the transformed element to an empty numpy array of shape (0, m, k)
result = np.empty(shape=(0, m, k))
for element in elements:
result = np.append(result, [some_operation(element)], axis=0)
What's the efficient way to apply some, let's say, "operation" on numpy array of shape (n, m, k)? I guess there is a more "numpy" approach.
Many thanks.
I think map is the most appropriate function for this

Combining list of 2D numpy arrays

How do I combine N, 2D numpy arrays (of dimension R x C) to create a 3D numpy array of shape (N, R, C)? Right now, the N-2D numpy arrays are contained inside a list, and I want that to become a 3D numpy array. Let's say X is my list of 2D numpy arrays, if I just do np.array(X), I get something of shape (N,). If I do np.vstack(X), I get something of shape (N x R, C). How do I solve this problem?
You can use np.stack:
test = np.stack([np.ones([2, 3]) for _ in range(4)])
print(test.shape) # (4, 2, 3)
you could just use :
np.array([np.array(x) for x in ArrayList])

How to multiply a vector by an array/matrix element-wise in numpy?

I have a multidimensional array a whose shape is (32,3,5,5) and an array v with a shape of (32,). How could I multiply (i,3,5,5) with (i,) for each i using numpy other than a for-loop?
With a and v as the two arrays, few approaches could be suggested -
a*v[:,None,None,None]
a*v.reshape(-1, *[1]*3)
(a.T * v).T
np.einsum('i...,i->i...', a, v)

Divide an array of arrays by an array of scalars

If I have an array, A, with shape (n, m, o) and an array, B, with shape (n, m), is there a way to divide each array at A[n, m] by the scalar at B[n, m] without a list comprehension?
>>> A.shape
(4,173,1469)
>>> B.shape
(4,173)
>>> # Better way to do:
>>> np.array([[A[i, j] / B[i, j] for j in range(len(B[i]))] for i in range(len(B))])
The problem with a list comprehension is that it is slow, it doesn't return an array (so you have to np.array(_) it, which makes it even slower), it is hard to read, and the whole point of numpy was to move loops from Python to C++ or Fortran.
If A was of shape (n) and B was a scalar (of shape ( )), then this would be trivial: A / B, but this property does not scale with dimensions
>>> A / B
ValueError: operands could not be broadcast together with shapes (4,173,1469) (4,173)
I am looking for a fast way to do this (preferably not by tiling B to an array of shape (n, m, o), and preferably using native numpy tools).
You are absolutely right, there is a better way, I think you are getting the spirit of numpy.
The solution in your case is that you have to add a new dimension to B that consists of one entry in that dimension:
so if your A is of shape (n,m,o) your B has to be of shape (n,m,1) and then you can use the native broadcasting to get your operation "A/B" done.
You can just add that dimension to be by adding a "newaxis" to B there.
import numpy as np
A = np.ones(10,5,3)
B = np.ones(10,5)
Result = A/B[:,:,np.newaxis]
B[:,:,np.newaxis] --> this will turn B into an array of shape of (10,5,1)
From here, the rules of broadcasting are:
When operating on two arrays, NumPy compares their shapes
element-wise. It starts with the trailing dimensions, and works its
way forward. Two dimensions are compatible when
they are equal, or
one of them is 1
Your dimensions are n,m,o and n,m so not compatible.
The / division operator will work using broadcasting if you use:
o,n,m divided by n,m
n,m,o divided by n,m,1

Categories