Fastest method to create 2D numpy array whose elements are in range
Can use np.indices
or np.meshgrid
for more advanced indexing:
>>> data=np.indices((512,512)).swapaxes(0,2).swapaxes(0,1)>>> data.shape(512, 512, 2)>>> data[5,0]array([5, 0])>>> data[5,25]array([ 5, 25])
This may look odd because its really made to do something like this:
>>> a=np.ones((3,3))>>> ind=np.indices((2,1))>>> a[ind[0],ind[1]]=0>>> aarray([[ 0., 1., 1.], [ 0., 1., 1.], [ 1., 1., 1.]])
A mgrid
example:
np.mgrid[0:512,0:512].swapaxes(0,2).swapaxes(0,1)
A meshgrid example:
>>> a=np.arange(0,512)>>> x,y=np.meshgrid(a,a)>>> ind=np.dstack((y,x))>>> ind.shape(512, 512, 2)>>> ind[5,0]array([5, 0])
All are equivalent ways of doing this; however, meshgrid
can be used to create non-uniform grids.
If you do not mind switching row/column indices you can drop the final swapaxes(0,1)
.
You can use np.ogrid
here. Instead of storing a tuple
, store it in a 3D array.
>>> t_row, t_col = np.ogrid[0:512, 0:512]>>> a = np.zeros((512, 512, 2), dtype=np.uint8)>>> t_row, t_col = np.ogrid[0:512, 0:512]>>> a[t_row, t_col, 0] = t_row>>> a[t_row, t_col, 1] = t_col
This should do the trick. Hopefully you can use this, instead of the tuple.
Chintak
The example in the question is not completely clear - either extra commas are missing or extra brakets.
This one - example ranges 3, 4 for clarity - provides the solution for the first variant and produces a 2D array in effect (as the question title suggests) - "listing" all coordinates:
>>> np.indices((3,4)).reshape(2,-1).Tarray([[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]])
The other variant was already shown in another answer by using 2x .swapaxes()
- but it could also be done with one np.rollaxis()
(or the new np.moveaxis()
) :
>>> np.rollaxis(np.indices((3,4)), 0, 2+1)array([[[0, 0], [0, 1], [0, 2], [0, 3]], [[1, 0], [1, 1], [1, 2], [1, 3]], [[2, 0], [2, 1], [2, 2], [2, 3]]])>>> _[0,1]array([0, 1])
This method also works the same for N-dimensional indices, e.g.:
>>> np.rollaxis(np.indices((5,6,7)), 0, 3+1)
Note: The function np.indices
works indeed (C-speed) fast for big ranges.