1

I am new to numpy and am trying to find a Pythonic :) way to generate a regular 3D grid of points.

With numpy, the ndindex function almost does what I want, but I gather that it only works with integers.

import numpy as np
ind=np.ndindex(2,2,1)
for i in ind:
    print(i)


>>>(0, 0, 0)
(0, 1, 0)
(1, 0, 0)
(1, 1, 0)

I basically want the same thing but using floats to define the values.

I define the dimensions of a box and the number of x, z, and z subdivisions.

Let's start by creating the x, y, and z dimension linear spaces.

import numpy as np
corner1 = [0.0, 0.0, 0.0]
corner2 = [1.0, 1.0, 1.0]

nx, ny, nz = 5, 3, 7

xspace = np.linspace(corner1[0], corner2[0], nx)
yspace = np.linspace(corner1[1], corner2[1], ny)
zspace = np.linspace(corner1[2], corner2[2], nz)

Now, how should I combine these to give me an array of all the points in my grid? Thank you for your time!

Jean-Rémy Revy
  • 5,607
  • 3
  • 39
  • 65
feedMe
  • 3,431
  • 2
  • 36
  • 61
  • 1
    Possible duplicate ( http://stackoverflow.com/questions/1827489/numpy-meshgrid-in-3d ) – mgilson May 18 '12 at 15:04
  • @mgilson, I think feedMe may be asking something slightly different; `ndindex` returns a generator, not an array. But it's not 100% clear from the question. – senderle May 18 '12 at 15:36
  • Sorry if you found my question unclear. I need to read up on generators next. – feedMe May 18 '12 at 17:03

2 Answers2

3

I find your question a bit confusing, because ndindex returns a generator, but you seem to be asking for an n-dimensional array. A generator is quite easy:

>>> list(numpy.broadcast(*numpy.ix_(x, y, z)))
[(0.0, 0.0, 0.0),
 (0.0, 0.0, 1.0),
 (0.0, 0.5, 0.0),
 (0.0, 0.5, 1.0),
 (0.0, 1.0, 0.0),
 (0.0, 1.0, 1.0),
 (1.0, 0.0, 0.0),
 (1.0, 0.0, 1.0),
 (1.0, 0.5, 0.0),
 (1.0, 0.5, 1.0),
 (1.0, 1.0, 0.0),
 (1.0, 1.0, 1.0)]

To pack it into an array, you could create an array and reshape it, remembering that the value triplet is its own dimension (hence the extra 3 at the end).

>>> numpy.array(list(numpy.broadcast(*numpy.ix_(x, y, z)))).reshape((2, 3, 2, 3))
array([[[[ 0. ,  0. ,  0. ],
         [ 0. ,  0. ,  1. ]],

        [[ 0. ,  0.5,  0. ],
         [ 0. ,  0.5,  1. ]],

        [[ 0. ,  1. ,  0. ],
         [ 0. ,  1. ,  1. ]]],


       [[[ 1. ,  0. ,  0. ],
         [ 1. ,  0. ,  1. ]],

        [[ 1. ,  0.5,  0. ],
         [ 1. ,  0.5,  1. ]],

        [[ 1. ,  1. ,  0. ],
         [ 1. ,  1. ,  1. ]]]])
senderle
  • 145,869
  • 36
  • 209
  • 233
  • Thanks, senderle. I now have the following that does what I wanted. `a = list(np.broadcast(*np.ix_(xspace, yspace, zspace)))` :) – feedMe May 18 '12 at 16:47
1

How about simply that:

xyz = numpy.mgrid[0:3:0.1, 0:2:0.2, 0:1:0.5]
print xyz
array([[[[ 0. ,  0. ],
     [ 0. ,  0. ],
     [ 0. ,  0. ],
     ...,

    [[ 0.1,  0.1],
     [ 0.1,  0.1],
     [ 0.1,  0.1],
     ...,
    [[ 0.2,  0.2],
     [ 0.2,  0.2],
     [ 0.2,  0.2]]
    ...,
    [[ 2.9,  2.9],
     [ 2.9,  2.9],
     [ 2.9,  2.9],
    ...
   [[[ 0. ,  0. ],
     [ 0.2,  0.2],
     [ 0.4,  0.4],
     ...,
     [ 0. ,  0.5],
     [ 0. ,  0.5],
     [ 0. ,  0.5]]]])
sega_sai
  • 8,328
  • 1
  • 29
  • 38