I have a numpy nd array. A simplified version of my task is to take a vector from along each axis. To illustrate:
import numpy
x = numpy.array(range(24)).reshape((2,3,4))
x0 = x[0,0,:]
x1 = x[0,:,0]
x2 = x[:,0,0]
However I do not necessarily know the number of dimensions x will have. So the challenge is how to place the colon : indexing operator in a variable location. An example of what such syntax could look like:
n = x.ndim
ind = list(np.zeros(n))
dim = 0
ind[dim] = ':'
y = x[ind]
or
y = indexer.index(x,ind)
for some module indexer. I could write it, but I feel like this must already be solved, I can't be the only one who wants to do this. In MATLAB, for example, you can do this with the subsref() function.
Does any such construct exist in python / numpy / other module?
A colon by itself means fetch everything. A colon on the right side of an index means everything after the specified index. A colon on the left side of an index means everything before, but not including, the index. And if we use a negative index, it means get elements from the end, going backwards.
In Python, a colon is required at the beginning of every block of code. It is easier to explain with an example. Notice how at the end of the if statement I have a colon. This tells Python that the next line of indented code should only be run IF the condition is true.
Individual values stored in an array can be accessed with indexing. Where <value> is the value stored in the array, <array> is the array object name and [index] specifies the index or location of that value. In the array above, the value 6 is stored at index 2.
Get the index of elements in the Python loopCreate a NumPy array and iterate over the array to compare the element in the array with the given array. If the element matches print the index.
As suggested from numpy
's documentation about indexing you can use the slice
built-in function and tuple concatenation to create variable indexes.
In fact the :
in the subscript is simply the literal notation for a slice
literal.
In particular :
is equivalent to slice(None)
(which, itself, is equivalent to slice(None, None, None)
where the arguments are start
, stop
and step
).
For example:
a[(0,) * N + (slice(None),)]
is equivalent to:
a[0, 0, ..., 0, :] # with N zeros
The :
notation for slices can only be used directly inside a subscript. For example this fails:
In [10]: a[(0,0,:)]
File "<ipython-input-10-f41b33bd742f>", line 1
a[(0,0,:)]
^
SyntaxError: invalid syntax
To allow extracting a slice from an array of arbitrary dimensions you can write a simple function such as:
def make_index(num_dimension, slice_pos):
zeros = [0] * num_dimension
zeros[slice_pos] = slice(None)
return tuple(zeros)
And use it as in:
In [3]: a = np.array(range(24)).reshape((2, 3, 4))
In [4]: a[make_index(3, 2)]
Out[4]: array([0, 1, 2, 3])
In [5]: a[make_index(3, 1)]
Out[5]: array([0, 4, 8])
In [6]: a[make_index(3, 0)]
Out[6]: array([ 0, 12])
You can generalize make_index
to do any kind of things. The important thing to remember is that it should, in the end, return a tuple
containing either integers or slice
s.
You could compose an string with the code selecting the dimension you want and use eval to execute that code string.
An start is:
n = 2
sel = "0,"*(n-1) + ":"
eval('x[' + sel + ']')
To get exactly what you want, thinks are a little bit more complicated (but not so much):
ind = 2
n = 3
sel = "".join([ ("0" if i != ind else ":") + ("," if i < n-1 else "") for i in xrange(n)])
eval('x[' + sel + ']')
It is the same strategy that is used for Dynamic SQL.
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