23

I have the following code:

a = torch.randint(0,10,[3,3,3,3])
b = torch.LongTensor([1,1,1,1])

I have a multi-dimensional index b and want to use it to select a single cell in a. If b wasn't a tensor, I could do:

a[1,1,1,1]

Which returns the correct cell, but:

a[b]

Doesn't work, because it just selects a[1] four times.

How can I do this? Thanks

2 Answers 2

13

A more elegant (and simpler) solution might be to simply cast b as a tuple:

a[tuple(b)]
Out[10]: tensor(5.)

I was curious to see how this works with "regular" numpy, and found a related article explaining this quite well here.

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

5 Comments

Is there any way of making this solution work with a list of indices?
Turns out a[list(b)] works, too. Interesting. Or are you referring to a "list of elements in the list" (i.e., something like b = [[1,1,1,1], [1,1,1,2], [2,3,1,2]]?
Um... Can we do this without converting our index tensor to a tuple? (let's say it's large and resides on GPU, making a tuple of it pulls all the values to CPU, both an overhead and forcing the GPU to wait on the CPU or vice versa).
I haven't worked with it in a while, so I cannot confidently answer your question. My intuition tells me that it isn't possible, and you are going to have to move data. I'm happy to be proven wrong, though, so maybe this could be a separate question?
It is worth mentioning that this even works when you want to select more than one element: b=tuple(torch.tensor([[1,1,1,1],[2,1,1,1]]).T), a[b].
11

You can split b into 4 using chunk, and then use the chunked b to index the specific element you want:

>> a = torch.arange(3*3*3*3).view(3,3,3,3)
>> b = torch.LongTensor([[1,1,1,1], [2,2,2,2], [0, 0, 0, 0]]).t()
>> a[b.chunk(chunks=4, dim=0)]   # here's the trick!
Out[24]: tensor([[40, 80,  0]])

What's nice about it is that it can be easily generalized to any dimension of a, you just need to make number of chucks equal the dimension of a.

3 Comments

Added bonus for being able to use multiple indices at once which I didn't account for in my question. Tested this and it works, although it's worth noting I need to squeeze the output. Thanks!
@Chum-ChumScarecrows thank you for accepting, but AFAIK dennlinger's answer also generalized to multiple indices. I suppose you should accept his.
Thank you! I have been looking far and wide for this kind of generalized indexing. Very surprised PyTorch doesn't support this natively, i.e. a[b] without all the extra operations

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.