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

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

Related

how to index a numpy array using another numpy array with different number of dimensions

I have an array of shape (B, N, 3) and an array of indexes with shape (B, M) with M<N
I want to get, for each item in B, M elements at the indexes indicated by the array of indexes, getting an array of shape (B, M, 3)
What I have tried with no success
array[indexes]
array[indexes.to_list()]
I am sure there is a fancy way of doing this but I haven't found it. Any advice?

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])

Why does this array indexing in numpy work?

I've got some numpy 2d arrays:
x, of shape(N,T)
W, of shape(V,D)
they are described as the following:
"Minibatches of size N where each sequence has length T. We assume a vocabulary of V words, assigning each to a vector of dimension D."(This is a question from cs231 A3.)
I want an output array of shape(N, T, D), where i can match the N elements to the desired vectors.
First I came out with the solution using a loop to run through all the elements in the first row of x:
for n in range(N):
out[n, :, :] = W[x[n, :]]
Then I go on to experiment with the second solution:
out = W[x]
Both solutions gave me the right answer, but why does the second solution work? Why can I index a 3d array in a 2d array?

multiply multidimensional arrays in 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])

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