Why can't I index an ndarray using a list of tuple indices like so?
idx = [(x1, y1), ... (xn, yn)] X[idx]
Instead I have to do something unwieldy like
idx2 = numpy.array(idx) X[idx2[:, 0], idx2[:, 1]] # or more generally: X[tuple(numpy.vsplit(idx2.T, 1)[0])]
Is there a simpler, more pythonic way?
ndarrays can be indexed using the standard Python x[obj] syntax, where x is the array and obj the selection. There are different kinds of indexing available depending on obj: basic indexing, advanced indexing and field access.
A numpy array is a grid of values, all of the same type, and is indexed by a tuple of nonnegative integers. The number of dimensions is the rank of the array; the shape of an array is a tuple of integers giving the size of the array along each dimension.
Numpy with Python It is possible to make a selection from ndarray that is a non-tuple sequence, ndarray object of integer or Boolean data type, or a tuple with at least one item being a sequence object. Advanced indexing always returns a copy of the data. As against this, the slicing only presents a view.
The most import data structure for scientific computing in Python is the NumPy array. NumPy arrays are used to store lists of numerical data and to represent vectors, matrices, and even tensors.
You can use a list of tuples, but the convention is different from what you want. numpy
expects a list of row indices, followed by a list of column values. You, apparently, want to specify a list of (x,y) pairs.
http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing The relevant section in the documentation is 'integer array indexing'.
Here's an example, seeking 3 points in a 2d array. (2 points in 2d can be confusing):
In [223]: idx Out[223]: [(0, 1, 1), (2, 3, 0)] In [224]: X[idx] Out[224]: array([2, 7, 4])
Using your style of xy pairs of indices:
In [230]: idx1 = [(0,2),(1,3),(1,0)] In [231]: [X[i] for i in idx1] Out[231]: [2, 7, 4] In [240]: X[tuple(np.array(idx1).T)] Out[240]: array([2, 7, 4])
X[tuple(zip(*idx1))]
is another way of doing the conversion. The tuple()
is optional in Python2. zip(*...)
is a Python idiom that reverses the nesting of a list of lists.
You are on the right track with:
In [242]: idx2=np.array(idx1) In [243]: X[idx2[:,0], idx2[:,1]] Out[243]: array([2, 7, 4])
My tuple()
is just a bit more compact (and not necessarily more 'pythonic'). Given the numpy
convention, some sort of conversion is necessary.
(Should we check what works with n-dimensions and m-points?)
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