3

Consider a numpy ndarray M of shape (say) (a,b,c) and a list of coordinates [(b0,c0),(b1,c1),...,(bn,cn)].

I want the following collection of vectors: [M[:,b0,c0],M[:,b1,c1],...,M[:,bn,cn]]. How can I achieve this with list comprehension?

EDIT: I need a solution that works for any number of dimensions, i.e. something that returns a list like the one above also in the case (say) M.shape = (a,b,c,d) and coordinates = [(b0,c0,d0),...,(bn,cn,dn)], and higher-dimensional cases as well.

2 Answers 2

8

You don't want to do this with a list comprehension. "Fancy indexing" can do the whole thing in one go. I'd recommend:

inds = [(b0,c0),(b1,c1),...,(bn,cn)]

#inds_array[0] = [b0, b1, b2, ...]
inds_array = np.moveaxis(np.array(inds), -1, 0)

M[np.index_exp[:] + tuple(inds_array)]

Demo:

>>> x, y, z = np.ogrid[:2,:4,:5]
>>> M = 100*x + 10*y + z
>>> M.shape
(2, 4, 5)
>>> inds = [(0, 0), (2, 1), (3, 4), (1, 2)]
>>> inds_array = np.moveaxis(np.array(inds), -1, 0); inds_array
array([[0, 2, 3, 1],
       [0, 1, 4, 2]])
>>> M[np.index_exp[:] + tuple(inds_array)]  # same as M[:, [0, 2, 3, 1], [0, 1, 4, 2]]
array([[  0,  21,  34,  12],
       [100, 121, 134, 112]])
Sign up to request clarification or add additional context in comments.

1 Comment

It might help to show what that indexing expression looks like: slice(None), ..... I had to look up index_exp to see how it's different from s_, and without running an example I can't picture inds_array.
5

If you want a list of these vectors you can simply use:

[M[:,bi,ci] for bi,ci in coordinates]

where coordinates is of course your list:

coordinates = [(b0,c0),(b1,c1),...,(bn,cn)]

EDIT: in case you want multivariate slicing, you can call the __getitem__ method with a slice(None) and the remaining indices:

[M.[(slice(None),*coord)] for coord in coordinates]

for ; or:

[M[(slice(None),)+coord] for coord in coordinates]

for other versions.

5 Comments

Dang it! beat me by a few seconds.
Thanks! This of course works, but I realized that I simplified my problem too much when writing the question. Let me edit it.
@Ziofil: but you explicitly ask to use list comprehension. didn't dv btw.
@Ziofil: does the updated example works (in Python-3.5)?
Downvote for calling .__getitem__( directly. There only reason to do that is super, and this is not that

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.