If I have a random function like func(x,y) = cos(x) + sen(y) + x*y how can I apply it to all the pairs of elements in 2 arrays?
I found https://docs.scipy.org/doc/nu
One way to solve this is broadcasting:
import numpy as np
def func(x, y):
x, y = np.asarray(x)[:, None], np.asarray(y)
return np.cos(x) + np.sin(y) + x*y
The [:, None]
adds another dimension to an array and therefor triggers NumPys broadcasting.
>>> func([1,2], [3,4])
array([[ 3.68142231, 3.78349981],
[ 5.72497317, 6.82705067]])
You could do this using a nested loop. Using a single element in one array, iterate through all the elements in the other array, then proceed to the next element in the first array and repeat.
This would be simple if you just want to print the result, if you want to store the results into another array, this would still work, it just uses a lot of resources.
As long as you make sure to write your function in such a way that it broadcasts properly, you can do
f(x_arr[:, None], y_arr)
to apply it to all pairs of elements in two 1-dimensional arrays x_arr
and y_arr
.
For example, to write your example function in a way that broadcasts, you'd write it as
def func(x, y):
return np.cos(x) + np.sin(y) + x*y
since np.cos
, np.sin
, +
, and *
broadcast and vectorize across arrays.
As for if it doesn't broadcast? Well, some might suggest np.vectorize
, but that has a lot of tricky things you have to keep in mind, like maintaining a consistent output dtype and not having side effects. If your function doesn't broadcast, I'd recommend just using list comprehensions:
np.array([[f(xval, yval) for yval in y_arr] for xval in x_arr])