2

Say I have two matrices:

X, Y = np.meshgrid(np.arange(0, 2, 0.1), np.arange(3, 5, 0.1))

And a function, something like:

def func(x) :
    return x[0]**2 + x[1]**2

How can I fill a matrix Z (of size np.shape(X)), where each entry is formed by calling func on the two corresponding values of X and Y, i.e.:

Z[i, j] = func([X[i, j], Y[i, j]])

Is there a way without using a double nested for-loop?

3
  • 4
    There is a typo x**[1] in the code. Commented Jan 2, 2016 at 18:48
  • 1
    Isn't this just Z = func([X, Y])? Commented Jan 2, 2016 at 18:56
  • 2
    It's best to avoid fractional ranges (like np.arange(0, 2, 0.1)) as floating point inaccuracies can cause unpredictable end-points. Use linspace instead. Commented Jan 2, 2016 at 18:58

2 Answers 2

3

This is also works as a vectorized form of function evaluation:

import numpy as np
X, Y = np.meshgrid(np.arange(0, 2, 0.1), np.arange(3, 5, 0.1))
def func(x) :
    return x[0]**2 + x[1]**2

Z = func([X,Y])
Sign up to request clarification or add additional context in comments.

Comments

3

For given numpy arrays X and Y, you could just do -

Zout = X**2 + Y**2

If you are actually constructing X and Y like that, there is a direct way to get Z with broadcasting and thus avoid np.meshgrid, like so -

Zout = np.arange(0, 2, 0.1)**2 + np.arange(3, 5, 0.1)[:,None]**2

2 Comments

I did mean for an arbitrary function, but your answer is still really informative. Could you possibly explain what the [:,None] does please?
@Tom That one is to extend the dimension by introducing a new axis with None. So, in this case, we convert a 1D to a 2D with it. And the idea with extending dimension(s) here is to bring in broadcasting.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.