Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indexing a numpy array with a list of tuples

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?

like image 916
Emre Avatar asked Feb 13 '15 01:02

Emre


People also ask

Can you index a NumPy array?

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.

Can you put tuples in a NumPy array?

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.

What is NumPy advanced indexing?

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.

Can NumPy array contain list?

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.


1 Answers

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?)

like image 163
hpaulj Avatar answered Sep 20 '22 09:09

hpaulj