Reputation: 3991
I've got the following definitions of 3 axes vectors:
arena = np.array([[-0.1, 0.1], [-0.1, 0.1], [0.06, 0.14]], dtype=np.float32)
resolution = np.array([0.01, 0.01, 0.01], dtype=np.float32)
axes_size = np.array((arena[:, 1] - arena[:, 0]) / resolution).astype(np.int32)
axes = [np.linspace(*arena[i], axes_size[i], endpoint=False, dtype=np.float32)
for i in np.arange(axes_size.shape[0])]
Note that axes_size = array([20, 20, 8], dtype=int32)
.
I'm trying to vectorize & generalize the following piece of code that create the cartesian product of axes
:
points = np.zeros([*axes_size, 3])
points[:, :, :, 0] = axes[0][:, None, None]
points[:, :, :, 1] = axes[1][None, :, None]
points[:, :, :, 2] = axes[2][None, None, :]
Note that points.shape = (20, 20, 8, 3)
.
I tried the following:
points = np.stack(np.meshgrid(*axes), axis=-1)
points = np.array(np.meshgrid(*axes)).T.reshape(-1, 3).T.reshape(*axes_size, 3)
Both lines seems to fail when comparing the results using np.testing.assert_allclose()
, and I can't seem to understand why.
Upvotes: 0
Views: 69
Reputation: 3254
The problem is that np.meshgrid
has a default setting that is not what most people would expect.
Add indexing='ij'
to create sane behavior:
points = np.stack(np.meshgrid(*axes, indexing='ij'), axis=-1)
This will pass the np.allclose
test.
The default of np.meshgrid
is indexing='xy'
which reverses the order of the first two axes. This is supposedly convenient for image data, where a 800x400 image (width 800, height 400) should be a shape (400, 800) array.
>>> np.meshgrid(np.arange(20), np.arange(21), np.arange(3))[0].shape
(21, 20, 3)
>>> np.meshgrid(np.arange(20), np.arange(21), np.arange(3), indexing='ij')[0].shape
(20, 21, 3)
If I deal with multidimensional arrays, I try to have different sizes along different axes, e.g. (20, 21, 8, 3)
rather than (20, 20, 8, 3)
so that I will catch this type of problem.
Upvotes: 1