# How to rearrange this tensor?

Hello,

I am searching around for a while, but still can not solve the problem I have at hand. Could somebody point me to the solution, or give an suggestion to this question?

I have a tensor,

A = [[row1], B = [1, 2, 1]
[row2],
[row3]]
tensor B indicates which group does each row of A belong to, and showing the group number

Question:

How can I rearrange A, such that rows for the same group can be grouped together, like:
A_after_rearrange = [[row1]
[row3],
[row2]]

If I correctly understood your question, this would work. If you want a more general way, you can easily extend it with a loop. It was not a matter of PyTorch, just Python programmingâ€¦

import torch

a = torch.tensor([[1,2,3],[4,5,6],[7,8,9]])
b = torch.tensor([1,2,1])

rearranged_a = torch.zeros(a.size())
rearranged_a[:2] = a[b==1]
rearranged_a[-1] = a[b==2]

This gives the correct answer! Thank you so much!

Excuse me, but a following question is:
If there is another quicker way instead of extending using for loop?

Try

``````a = torch.tensor([[1,2,3],[4,5,6],[7,8,9]])
b = torch.tensor([1,2,1])
_, inds = torch.sort(b)
rearranged_a = a[inds]
``````

Oh, right, I think this may be the best answer.

You misunderstood me: I just meant that you should use a for loop but only if you have to do more than two replacements and just for compactness. I also would say that how vector b is built is rather counterintuitive but I donâ€™t know from where it comes. I can guess some class labels. However, if instead of having b like this you manage to have b = [0,2,1], which gives the indeces where you want to place the rows, there exists a builtin method that does the job. Try, with b = [0,2,1]:

rearranged_a = torch.index_select(a,0,b)

Of course, same solution much more compact. I should have thought!

Thank you for giving the informative suggestions!

sorry, Iâ€™m back.

If I am using `torch.sort(b)` then the internal order of all `1`s in `b` is disturbed. It means the `inds=[2, 0, 1]`, not `inds=[0, 2, 1]`. Is there a way to get `b` sorted but not disturb elements internal ordering?

b is not modified by the method sort, inds is a new tensor, which gives the argsort of b. However I donâ€™t have clear your questionâ€¦

`_, inds = torch.sort(b)` will give `inds = [2, 0, 1]`. If I want `inds = [0, 2, 1]`, which means the ordering between two `1`s stay the same, then how should I do?

Look, if I run:

``````_, inds = torch.sort(b)
print(inds)
``````

I get:

``````[0, 2, 1]
``````

Are you sure you did not modify b?

What if you sort this tensor:

``````[1, 2, 3, 4, 4, 1, 2, 3, 2, 4, 3, 1, 3, 1, 2, 4]
``````

What will you get? I am getting:

``````[11,  0, 13,  5, 14,  6,  1,  8, 12,  7, 10,  2,  9,  4,  3, 15]
``````

Yes you are right, the behavior is not the expected.

Hi, I have manage to get expected sort using `numpy.argsort(b)`. This will give stable sort. Thank you for your reply again.

1 Like