How to generate a 3-d matrix of coordindates numpy.meshgrid

Question:

I need to generate a matrix, say A, and the element of this matrix, say a_{ij}=(x_i,y_j) represents the coordinate of this point. I need the coordinate information to do further calculations. It seems if I could get this matrix, the following calculation should be more efficient than I use double loop (i:0:len(x_i), j:0:len(y_j)) to calculate each point.
The coordinate information is trivial:

num_xmesh = nx
num_ymesh = ny
x_start = xs
x_end = xe
y_start = ys
y_end = ye
x_grid=np.linspace(x_start,x_end,num_xmesh)
y_grid=np.linspace(y_start,y_end,num_ymesh)

I want to know how to generate this kind of matrix with numpy.

Asked By: yangyang

||

Answers:

You can stack the arrays returned by np.meshgrid using np.stack to produce a 3D array with "spatial" coordinates in the first two dimensions and the coordinate values in the last dimension:

import numpy as np

x = [1, 2, 3]
y = [4, 5, 6]


a = np.stack(np.meshgrid(x, y, indexing="ij"), axis=-1)

>>> print(a.shape)
(3, 3, 2)

>>> print(a)
[[[1 4]
  [1 5]
  [1 6]]

 [[2 4]
  [2 5]
  [2 6]]

 [[3 4]
  [3 5]
  [3 6]]]

>>> print(a[0, 0])
[1 4]  # a_00 = (x_0, y_0)

>>> print(a[0, 1])
[1 5]  # a_01 = (x_0, y_1)

>>> print(a[1, 0])
[2 4]  # a_10 = (x_1, y_0)
Answered By: Brian61354270

Adjust the values of num_xmesh, num_ymesh, x_start, x_end, y_start, and y_end according to your specific requirements to generate the desired coordinate matrix A.

num_xmesh = 5  
num_ymesh = 4  
x_start = 0
x_end = 10
y_start = 0
y_end = 8

x_grid = np.linspace(x_start, x_end, num_xmesh)
y_grid = np.linspace(y_start, y_end, num_ymesh)

X, Y = np.meshgrid(x_grid, y_grid)

A = np.array([X.flatten(), Y.flatten()]).T

print("Matrix A (Coordinates):")
print(A)
Answered By: prakash888kp

You might consider using np.indices or
np.mgrid to generate a single array that needs no stacking:

num_mesh = [nx, ny]
start = [xs, ys]
end = [xe, ye]
grid = (np.indices(num_mesh) * (end - start) + start).transpose(1, 2, 0)

OR

grid = (np.mgrid[:nx, :ny] * (end - start) + start).transpose(1, 2, 0)

The transpose is necessary if you want to have the coordinates in the last dimension rather than the first. It’s not clear how you plan on using this grid, so it might not be necessary at all.

For that matter, you might be able to use broadcasting to avoid allocating the entire matrix to begin with. You might be able to index/reshape your original grid arrays, or equivalently use indices(..., sparse=True) or ogrid instead of mgrid.

The advantage of this approach is that it allocates a single array of coordinates once instead of first allocating the components and then copying them into the result buffer. That makes it more memory efficient and probably faster too. It won’t matter for small examples in which it’s not the bottleneck, but for large arrays you might notice a difference.

Answered By: Mad Physicist
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.