How to rearrange this tensor?

zcajiayin: <p>Hello,</p>
<p>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?</p>
<p>I have a tensor,</p>
<p>A = [[row1],    B = [1, 2, 1]<br>
[row2],<br>
[row3]]<br>
tensor B indicates which group does each row of A belong to, and showing the group number</p>
<p>Question:</p>
<p>How can I rearrange A, such that rows for the same group can be grouped together, like:<br>
A_after_rearrange = [[row1]<br>
[row3],<br>
[row2]]</p>

gioperin: <p>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…</p>
<p>import torch</p>
<p>a = torch.tensor([[1,2,3],[4,5,6],[7,8,9]])<br>
b = torch.tensor([1,2,1])</p>
<p>rearranged_a = torch.zeros(a.size())<br>
rearranged_a[:2] = a[b==1]<br>
rearranged_a[-1] = a[b==2]</p>

zcajiayin: <p>This gives the correct answer! Thank you so much!</p>
<p>Excuse me, but a following question is:<br>
If there is another quicker way instead of extending using for loop?</p>

liyz15: <p>Try</p>
<pre><code class="lang-auto">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]
</code></pre>

zcajiayin: <p>Oh, right, I think this may be the best answer.</p>

gioperin: <p>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]:</p>
<p>rearranged_a = torch.index_select(a,0,b)</p>

gioperin: <p>Of course, same solution much more compact. I should have thought!</p>

zcajiayin: <p>Thank you for giving the informative suggestions!</p>

zcajiayin: <p>sorry, I’m back.</p>
<p>If I am using <code>torch.sort(b)</code> then the internal order of all <code>1</code>s in <code>b</code> is disturbed. It means the <code>inds=[2, 0, 1]</code>, not <code>inds=[0, 2, 1]</code>. Is there a way to get <code>b</code> sorted but not disturb elements internal ordering?</p>

gioperin: <p>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…</p>

zcajiayin: <p>Thank you for your answer.</p>
<p><code>_, inds = torch.sort(b)</code> will give <code>inds = [2, 0, 1]</code>. If I want <code>inds = [0, 2, 1]</code>, which means the ordering between two <code>1</code>s stay the same, then how should I do?</p>

gioperin: <p>Look, if I run:</p>
<pre><code>_, inds = torch.sort(b)
print(inds)
</code></pre>
<p>I get:</p>
<pre><code>[0, 2, 1]
</code></pre>
<p>Are you sure you did not modify b?</p>

zcajiayin: <p>What if you sort this tensor:</p>
<pre><code class="lang-auto">[1, 2, 3, 4, 4, 1, 2, 3, 2, 4, 3, 1, 3, 1, 2, 4]
</code></pre>
<p>What will you get? I am getting:</p>
<pre><code class="lang-auto">[11,  0, 13,  5, 14,  6,  1,  8, 12,  7, 10,  2,  9,  4,  3, 15]
</code></pre>

gioperin: <p>Yes you are right, the behavior is not the expected.</p>

zcajiayin: <p>Hi, I have manage to get expected sort using <code>numpy.argsort(b)</code>. This will give stable sort. Thank you for your reply again.</p>