How to get the row index of specific values in tensor

username: isalirezag
cooked: <p>Sorry for the stupid question, but i cannot find a fast way to solve my issue, so i thought maybe the experts here can help me with that or maybe pytorch has a function that already does this in a fast way.</p>
<p>I have a  Tensor with size of <code>BxRxC</code>:<br>
e.g.<br>
here <code>T</code> has dimension of 1x3x4<br>
<code>T = torch.round(torch.rand(1,3,4)*10)</code><br>
<code>T =</code><br>
<code>6 8 10 8</code><br>
<code>2 4 7 2</code><br>
<code>5 0 4 1</code><br>
Now i have another tensor (<code>K</code>) with way larger size, i know that tensor <code>K</code> includes values of each row of Tensor tensor <code>T</code> somewhere in it  as well as other values, but i dont know where they are<br>
e.g.<br>
here <code>K</code> has dimension of <code>1x9x4</code><br>
<code>K = torch.cat((torch.round(torch.rand(1,3,4)*10),T, torch.zeros(1,3,4)),1)</code><br>
K =<br>
<code>5 7 8 1</code><br>
<code>8 2 7 8</code><br>
<code>0 10 8 8</code><br>
<code>6 8 10 8</code><br>
<code>2 4 7 2</code><br>
<code>5 0 4 1</code><br>
<code>0 0 0 0</code><br>
<code>0 0 0 0</code><br>
<code>0 0 0 0</code></p>
<p>as we can see <code>K</code> has the values of  <code>T</code> in row: 1,4, and 5<br>
in terms of size B and C will always be the same in both <code>T</code> and <code>K</code>.<br>
How I can get the row indexes in <code>K</code> that includes the values in <code>T</code>?</p>
<p>Also if I have another tensor <code>D</code> and lets say I have the indexes for the rows from last steps, how I can extract only the values in the rows of tensor <code>D</code> based on the indexes that i got, meaning that if <code>D</code> is:<br>
<code>D = torch.round(torch.rand(1,9,4)*10)</code><br>
<code>D =</code><br>
<code>2 6 8 7</code><br>
<code>3 3 9 9</code><br>
<code>4 4 4 4</code><br>
<code>2 7 5 2</code><br>
<code>3 1 9 7</code><br>
<code>3 4 4 7</code><br>
<code>1 5 2 1</code><br>
<code>3 7 1 7</code><br>
<code>5 9 8 10</code></p>
<p>I want the output be<br>
<code>O =</code><br>
<code>2 7 5 2</code><br>
<code>3 1 9 7</code><br>
<code>3 4 4 7</code></p>
<p><code>my output will be the same size as T</code>,</p>
<p>P.s. I just multiplied the number with 10 to make it easier for reading purposes, they are not integer all the time.</p>

username: tumble-weed
cooked: <p>Get the difference between the common dimension of <code>K</code> and <code>T</code><br>
<code>d = T.unsqueeze(2) - K.unsqueeze(1)</code><br>
this will be of size <code>(1,3,7,4)</code>.  Where the rows were identical, we would have <code>0,0,0,0</code>. So sum together the last dimension: <code>dsum = d.sum(-1)</code><br>
Now find out where <code>dsum</code> has zeros:<br>
<code>loc = (dsum==0).nonzero()</code><br>
since all 3 rows were found somewhere in <code>K</code>, this will have size <code>3,3</code>, if only 2 rows were found this would have a shape <code>(2,3)</code>. You are interested in the locations inside <code>K</code>, so you need <code>loc[:,-1]</code></p>
<p>Assuming <code>D</code> is same size as <code>K</code> to take out the relevant rows you’d do:<br>
<code>D[:,loc[:,-1],:]</code></p>

username: isalirezag
cooked: <p>thanks a lot, it just had one minor proble, we should use <code>dsum = torch.abs(d).sum(-1)</code> instead of <code>d.sum(-1)</code>, because the sum of numbers might lead to zero, although they are not all zeros.<br>
see the following e.g.</p>
<pre><code class="lang-auto">    T = torch.round(torch.rand(1,3,4)*10)
    4 3 6 3
    1 0 5 8
    1 10 4 8
    K = torch.cat((torch.round(torch.rand(1,3,4)*10),T, torch.zeros(1,3,4)),1)
    0 9 1 9
    3 3 4 7
    9 3 1 3
    4 3 6 3
    1 0 5 8
    1 10 4 8
    0 0 0 0
    0 0 0 0
    0 0 0 0
    D = torch.round(torch.rand(1,9,4)*10)
    3 6 7 2
    4 0 5 9
    4 2 5 10
    4 4 9 2
    2 0 2 6
    2 1 4 0
    1 4 8 3
    4 3 8 0
    2 3 9 10
    d = T.unsqueeze(2) - K.unsqueeze(1)
    (0 ,0 ,.,.) =
    4 -6 5 -6
    1 0 2 -4
    -5 0 5 0
    0 0 0 0
    3 3 1 -5
    3 -7 2 -5
    4 3 6 3
    4 3 6 3
    4 3 6 3

    (0 ,1 ,.,.) =
    1 -9 4 -1
    -2 -3 1 1
    -8 -3 4 5
    -3 -3 -1 5
    0 0 0 0
    0 -10 1 0
    1 0 5 8
    1 0 5 8
    1 0 5 8

    (0 ,2 ,.,.) =
    1 1 3 -1
    -2 7 0 1
    -8 7 3 5
    -3 7 -2 5
    0 10 -1 0
    0 0 0 0
    1 10 4 8
    1 10 4 8
    1 10 4 8

    dsum = d.sum(-1)
    (0 ,.,.) =
    -3 -1 0 0 2 -7 16 16 16
    -5 -3 -2 -2 0 -9 14 14 14
    4 6 7 7 9 0 23 23 23
    [torch.FloatTensor of size 1x3x9]

    loc = (dsum==0).nonzero()
    0 0 2
    0 0 3
    0 1 4
    0 2 5
    loc[:,-1]
    2
    3
    4
    5
    D[:,loc[:,-1],:]
    (0 ,.,.) =
    4 2 5 10
    4 4 9 2
    2 0 2 6
    2 1 4 0
    [torch.FloatTensor of size 1x4x4]

</code></pre>

username: isalirezag
cooked: <p>on another note, can you help me understand what <code>loc = (dsum==0).nonzero()</code> does?<br>
so if the output of <code>(dsum==0)</code> is</p>
<pre><code class="lang-auto">  0  0  1  0  0  0
  0  0  0  1  0  0
</code></pre>
<p>then<br>
<code>(dsum==0).nonzero()</code><br>
gives us</p>
<pre><code class="lang-auto"> 0  0  2
 0  1  3
</code></pre>
<p>I understand that 2 and 3 are the indices, but what is 1 here?</p>

username: ptrblck
cooked: <p>The result gives you a tensor containing indices for all nonzero occurrences in the shape <code>[num_nonzeros, dims]</code>.<br>
The first column (<code>loc[:, 0]</code>) gives the indices in dim0, the second one in dim1, etc.<br>
As <code>dsum</code> has three dimensions, the second row stands for <code>dsum[0, 1, 3]</code>.</p>

username: tumble-weed
cooked: <p>good catch. it should be sum of abs</p>

username: Abhishek_Kumar2
cooked: <p>The above code for determination of tensor index is very useful, lately I came across an anomaly when doing this operation.<br>
This is function I am using for determining index of host tensor from target tensor.</p>
<pre><code class="lang-auto">def get_index(host, target):
        diff = target.unsqueeze(1) - host.unsqueeze(0)
        dsum = torch.abs(diff).sum(-1)
        loc = (dsum == 0).nonzero()
        return loc[:, -1]
</code></pre>
<p>for example I wanted to extract the index from 2D Tensor of shape (40,2). Such that Target[:,1] = 0 and 1 . This is the result I got:</p>
<pre><code class="lang-auto">tensor([[0.0000, 0.0000],
        [1.0000, 0.0000],
        [0.0000, 0.1111],
        [1.0000, 0.1111],
        [0.0000, 0.2222],
        [1.0000, 0.2222],
        [0.0000, 0.3333],
        [1.0000, 0.3333],
        [0.0000, 0.4444],
        [1.0000, 0.4444],
        [0.0000, 0.5556],
        [1.0000, 0.5556],
        [0.0000, 0.7778],
        [1.0000, 0.7778],
        [0.0000, 0.8889],
        [1.0000, 0.8889],
        [0.0000, 1.0000],
        [1.0000, 1.0000]])
</code></pre>
<p>The value of 0.6667 is missing from this output. Can anyone explain this abnormality or am I doing something wrong. <a class="mention" href="/u/ptrblck">@ptrblck</a> could you please suggest anything.</p>

username: ptrblck
cooked: <p>You might be running into rounding errors due to the limited precision of floating point operations.<br>
Try to compare the <code>dsum</code> to a small <code>eps</code> via <code>dsum &lt;= eps</code> values instead of <code>dsum == 0</code>.</p>

username: Abhishek_Kumar2
cooked: <p>Thanks a ton, it solved my problem</p>