Scatter_sample like operation?

i have a tensor x = [2, 3, 2, 1, 2, 3, 2]
I want to randomly sample a number from all same number, e.g. randomly sample the 2 from all 2’s index, and get index may be 0, namely sampled the first 2; randomly sample the 3, and get index may be 5. and randomly sample the 1, get index 3 since only single 1 exists. so the return index may like [0, 5, 3] or mask: [1, 0, 0, 1, 0, 1, 0].
I dnt know how to implement this logic by pytorch? please kindly help me.

Thank you so much.

You could get all occurrences of the current number you would like to draw and randomly permute these indices:

x = torch.tensor([2, 3, 2, 1, 2, 3, 2])
to_sample = torch.as_tensor(2)
idx_all = (x == to_sample).nonzero()
idx = idx_all[torch.randperm(len(idx))[0]]
1 Like

@ptrblck Thanks.
However, if i want to iterate over all unique number, i have to use a python for loop:

x = torch.tensor([2, 3, 2, 1, 2, 3, 2])
unique = torch.unique(x)
for u in unique: #!!! time consuming!
    to_sample = u
    idx_all = (x == to_sample).nonzero()
    idx = idx_all[torch.randperm(len(idx))[0]]

any concise way to finish it without python for loop?
Thank you.

using numpy might be faster; why iterating over your list?
Something like this,

import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]

In that case, I would just sample the values using torch.multinomial:

x = torch.tensor([2, 3, 2, 1, 2, 3, 2])
unique = torch.unique(x)
weight = x.unsqueeze(0) == unique.unsqueeze(1)
torch.multinomial(weight.float(), num_samples=1)
1 Like