The torch.unique() function returns the unique values and the inverse indices, but unlike np.unique, doesn’t return the indices of the first occurrence of these unique values. Is there any way of doing this in pytorch without using a for loop for each unique value?
Hi,
I was wondering the same problem today, and I’ve found a tricky workaround (for sure not elegant).
Here’s the example code:
a = torch.rand(2,2)
a = torch.vstack([a, a[0]])
uni, rev_idxs = a.unique(dim=0, return_inverse=True)
first_occ_idxs = rev_idxs.unique()
print(a[first_occ_idxs])
If anyone can suggest a more elegant solution, I would adopt it.
Hi,
I came across the PyTorch Unique package, which implements the unique function as follows:
unique, inverse = torch.unique(x, sorted=True, return_inverse=True)
perm = torch.arange(inverse.size(0), dtype=inverse.dtype, device=inverse.device)
inverse, perm = inverse.flip([0]), perm.flip([0])
perm = inverse.new_empty(unique.size(0)).scatter_(0, inverse, perm)
Hey there.
Maybe it’s not relevant anymore, but here’s solution that i’ve used:
def find_first_occurence(x, value):
x_value_mask = (x==value).type(torch.int)
idx = torch.arange(1, x.shape[-1] + 1).unsqueeze(0) # so that "0" is going to be a marker for lack of occurence
idx = x_value_mask * idx
idx = torch.where(idx!=0, idx, float("nan"))
idx = idx.sort(-1).values[:, 0]
return idx
my_tensor = torch.tensor([
[0 ,0 , 2],
[0 ,1 , 1],
[1 ,4 , 0],
])
idx = find_first_occurence(obj_nrm, 1)