Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply a function / map values of each element in a 2d numpy array/matrix?

Tags:

numpy

Given the following numpy matrix:

import numpy as np mymatrix = np.matrix('-1 0 1; -2 0 2; -4 0 4')   matrix([[-1,  0,  1],         [-2,  0,  2],         [-4,  0,  4]]) 

and the following function (sigmoid/logistic):

import math def myfunc(z):     return 1/(1+math.exp(-z)) 

I want to get a new NumPy array/matrix where each element is the result of applying the myfunc function to the corresponding element in the original matrix.

the map(myfunc, mymatrix) fails because it tries to apply myfunc to the rows not to each element. I tried to use numpy.apply_along_axis and numpy.apply_over_axis but they are meant also to apply the function to rows or columns and not on an element by element basis.

So how can apply myfunc(z) to each element of myarray to get:

matrix([[ 0.26894142,  0.5       ,  0.73105858],         [ 0.11920292,  0.5       ,  0.88079708],         [ 0.01798621,  0.5       ,  0.98201379]]) 
like image 341
RubenLaguna Avatar asked Mar 04 '17 10:03

RubenLaguna


People also ask

How do you access the elements of a 2D NumPy array?

Indexing a Two-dimensional Array To access elements in this array, use two indices. One for the row and the other for the column. Note that both the column and the row indices start with 0. So if I need to access the value '10,' use the index '3' for the row and index '1' for the column.

Does map work with NumPy array?

Method 1: numpy.vectorize() function maps functions on data structures that contain a sequence of objects like NumPy arrays. The nested sequence of objects or NumPy arrays as inputs and returns a single NumPy array or a tuple of NumPy arrays.


2 Answers

Apparently, the way to apply a function to elements is to convert your function into a vectorized version that takes arrays as input and return arrays as output.

You can easily convert your function to vectorized form using numpy.vectorize as follows:

myfunc_vec = np.vectorize(myfunc) result = myfunc_vec(mymatrix) 

or for a one shot usage:

np.vectorize(myfunc)(mymatrix) 

As pointed out by @Divakar, it's better (performance-wise) if you can write an already vectorized function from scratch (using NumPy built ufuncs without using numpy.vectorize) like so:

def my_vectorized_func(m):     return 1/(1+np.exp(-m))  # np.exp() is a built-in ufunc  my_vectorized_func(mymatrix) 

Since numpy.exp is already vectorized (and math.exp wasn't) the whole expression 1/(1+np.exp(-m)) will be vectorized (and faster that applying my original function to each element).

The following complete example produced the required output:

import numpy as np mymatrix = np.matrix('-1 0 1; -2 0 2; -4 0 4') import math def myfunc(z):     return 1/(1+math.exp(-z))  np.vectorize(myfunc)(mymatrix) # ok, but slow  def my_vectorized_func(m):     return 1/(1+np.exp(-m))  my_vectorized_func(mymatrix) # faster using numpy built-in ufuncs 
like image 157
RubenLaguna Avatar answered Sep 17 '22 13:09

RubenLaguna


Just in case this helps, scipy has a sigmoid function you can directly call on a matrix.

like image 28
mithunpaul Avatar answered Sep 18 '22 13:09

mithunpaul