I want to create a 2d numpy array where every element is a tuple of its indices.
Example (4x5):
array([[[0, 0],
[0, 1],
[0, 2],
[0, 3],
[0, 4]],
[[1, 0],
[1, 1],
[1, 2],
[1, 3],
[1, 4]],
[[2, 0],
[2, 1],
[2, 2],
[2, 3],
[2, 4]],
[[3, 0],
[3, 1],
[3, 2],
[3, 3],
[3, 4]]])
I would create an python list
with the following list comprehension:
[[(y,x) for x in range(width)] for y in range(height)]
Is there a faster way to achieve the same, maybe with numpy methods?
Introduction to the JavaScript array indexOf() method To find the position of an element in an array, you use the indexOf() method. This method returns the index of the first occurrence the element that you want to find, or -1 if the element is not found.
"Index" describes the storage location. "Element" describes the contents of a location.
Creating a Array Array in Python can be created by importing array module. array(data_type, value_list) is used to create an array with data type and value list specified in its arguments.
Do you do this because you need it or just for sport? In the former case:
np.moveaxis(np.indices((4,5)), 0, -1)
np.indices
does precisely what its name suggests. Only it arranges axes differently to you. So we move them with moveaxis
As @Eric points out one attractive feature of this method is that it works unmodified at arbitrary number of dimensions:
dims = tuple(np.multiply.reduceat(np.zeros(16,int)+2, np.r_[0, np.sort(np.random.choice(16, np.random.randint(10)))]))
# len(dims) == ?
np.moveaxis(np.indices(dims), 0, -1) # works
Here's an initialization based method -
def create_grid(m,n):
out = np.empty((m,n,2),dtype=int) #Improvement suggested by @AndrasDeak
out[...,0] = np.arange(m)[:,None]
out[...,1] = np.arange(n)
return out
Sample run -
In [47]: create_grid(4,5)
Out[47]:
array([[[0, 0],
[0, 1],
[0, 2],
[0, 3],
[0, 4]],
[[1, 0],
[1, 1],
[1, 2],
[1, 3],
[1, 4]],
[[2, 0],
[2, 1],
[2, 2],
[2, 3],
[2, 4]],
[[3, 0],
[3, 1],
[3, 2],
[3, 3],
[3, 4]]])
Runtime test for all approaches posted thus far on (4,5)
grided and bigger sizes -
In [111]: %timeit np.moveaxis(np.indices((4,5)), 0, -1)
...: %timeit np.mgrid[:4, :5].swapaxes(2, 0).swapaxes(0, 1)
...: %timeit np.mgrid[:4,:5].transpose(1,2,0)
...: %timeit create_grid(4,5)
...:
100000 loops, best of 3: 11.1 µs per loop
100000 loops, best of 3: 17.1 µs per loop
100000 loops, best of 3: 17 µs per loop
100000 loops, best of 3: 2.51 µs per loop
In [113]: %timeit np.moveaxis(np.indices((400,500)), 0, -1)
...: %timeit np.mgrid[:400, :500].swapaxes(2, 0).swapaxes(0, 1)
...: %timeit np.mgrid[:400,:500].transpose(1,2,0)
...: %timeit create_grid(400,500)
...:
1000 loops, best of 3: 351 µs per loop
1000 loops, best of 3: 1.01 ms per loop
1000 loops, best of 3: 1.03 ms per loop
10000 loops, best of 3: 190 µs per loop
You can abuse numpy.mgrid
or meshgrid
for this purpose:
>>> import numpy as np
>>> np.mgrid[:4,:5].transpose(1,2,0)
array([[[0, 0],
[0, 1],
[0, 2],
[0, 3],
[0, 4]],
[[1, 0],
[1, 1],
[1, 2],
[1, 3],
[1, 4]],
[[2, 0],
[2, 1],
[2, 2],
[2, 3],
[2, 4]],
[[3, 0],
[3, 1],
[3, 2],
[3, 3],
[3, 4]]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With