57

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?

0

2 Answers 2

70

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

Sign up to request clarification or add additional context in comments.

2 Comments

How would you do this in 3 dimensions?
If X is 3d, it still needs a tuple of indexing arrays (or lists]. Nothing about this is specific to 2d.
4

Use a tuple of NumPy arrays which can be directly passed to index your array:

index = tuple(np.array(list(zip(*index_tuple))))
new_array = list(prev_array[index])

1 Comment

You actually don't need to convert to array, tuple(zip(*index_tuple)) will suffice

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.