Search code examples
pythonarraysnumpymatrixindices

Simpler way to create a matrix/list of indices?


I wonder what could be the easiest way to create a bi-dimensional array, that has for each row the indices to another multi-dimensional array.

For example, let's say I have a cube 4x4, the "indices matrix" would be the following:

np.concatenate([
    np.expand_dims(curr.ravel(),axis=0).T
    for curr
    in np.meshgrid(
        np.arange(4),
        np.arange(4),
        np.arange(4)
    )
],axis=1)

with the following result:

array([[0, 0, 0],
      [0, 0, 1],
      [0, 0, 2],
      [0, 0, 3],
      [1, 0, 0],
      [1, 0, 1],
      ...
      [2, 3, 2],
      [2, 3, 3],
      [3, 3, 0],
      [3, 3, 1],
      [3, 3, 2],
      [3, 3, 3]])

Besides the fact that it seems that the second column should be in place of the first, is there a more "numpythonic" way to create the same or similar matrix in a more compact way?

It would be nice if existed a function that just takes an arbitrary multi-dimensional array and returns it's index table.


Solution

  • You could use np.indices:

    >>> a = np.random.random((4,4,4))
    >>> np.indices(a.shape).reshape((a.ndim, -1)).T
    array([[0, 0, 0],
           [0, 0, 1],
           [0, 0, 2],
           [0, 0, 3],
           [0, 1, 0],
           [0, 1, 1],
    [...]
           [3, 3, 2],
           [3, 3, 3]])
    

    There are also other utilities like np.ndindex, depending on your use case. (FWIW I don't think getting the coordinates in the form you're looking for is going to be as helpful as you might think it is, but YMMV.)