0

let's say that I have the following function

def my_func(a,b):
    
    res = a[0] + a[1]*b
    
    return res

I know how to apply it to one element of a matrix:

import numpy as np
mydata = np.matrix([[1, 2], [3, 4]])
my_par = np.array([1, 2])
res = my_func(my_par,mydata[1,1])

I would like now to apply it to all the element of the matrix mydata. I have tried thus

myfunc_vec = np.vectorize(my_func)
res = myfunc_vec(my_par,mydata)

and I have the following error:

in my_func
    res = a[0] + a[1]*b
IndexError: invalid index to scalar variable.

I believe that the error is due to the fact that I pass two arguments to the function.

Is there any way to apply my function to all the element of the matrix without having an error?

diedro
  • 511
  • 1
  • 3
  • 15
  • Do you want `my_par` to be the same pair of values for every element of the matrix? If so, then your calculation is equivalent to `my_par[0] + my_par[1] * mydata`, so you could just do `res = my_func(my_par, mydata)` with no need for a vectorize step. – slothrop Jan 30 '23 at 17:03
  • What is your real function? You should maybe use broadcasting? – mozway Jan 30 '23 at 17:06

2 Answers2

0

I think the simplest way to do this would be to use a for loop. Make sure to also replace np.matrix() with np.array().

def my_func(a,b):  
    res = a[0] + a[1]*b  
    return res

import numpy as np
mydata = np.array([[1, 2], [3, 4]])
my_par = np.array([1, 2])
res = my_func(my_par,mydata[1,1])
res = np.zeros((len(mydata), len(mydata[0])))
for i in range(len(mydata)):
   for j in range(len(mydata[0])):
      res[i][j] = my_func(my_par, mydata[i][j])

print(res)

Output:

[[3. 5.]
 [7. 9.]]

Hope that helps!

  • It works for sure. However, I am looking for something more compact and efficient. A sort of apply with parameters but for numpy vector and not dataframe. – diedro Jan 30 '23 at 16:46
  • 1
    `np.vectorize` is just a `for` loop on the backend, it doesn't contribute to performance, just ease of use for certain functions, which in your case would require a bit more fiddling. See this post: https://stackoverflow.com/questions/35215161/most-efficient-way-to-map-function-over-numpy-array – Jacob Ivanov Jan 30 '23 at 16:54
0

You don't have to do anything. Just pass my_data instead of my_data[1,1] and rest everything will fall in place.

mydata = np.matrix([[1, 2], [3, 4]])
my_par = np.array([1, 2])
res = my_func(my_par,mydata)
print(res)

Output:

[[3 5]
 [7 9]]
MSS
  • 3,306
  • 1
  • 19
  • 50