Reverse operation of torch.unique

Viewed 214

In pytorch , unique (with return_count is True) operation do like this

[1,1,2,2,3,3] => ([1,2,3],[2,2,2])

Are there any reverse operations of torch.unique() ? i.e Given a unique list and its count , return the original list like

([1,2,3],[2,2,2]) = > [1,1,2,2,3,3]
2 Answers

If you include the return inverse parameter it will return the indices for where elements in the original input ended up in the returned unique list. Then you can use take to create a new tensor.

test_tensor = torch.tensor([1,1,2,2,3,3])
items, inverse, counts = test_tensor.unique(return_counts=True, return_inverse=True)
new_tensor = torch.take(items, inverse)
assert new_tensor.eq(test_tensor).all() # true

EDIT: If you only have a list and the counts this code should give you what you want using repeat. Not sure if a pure pytorch function exists.

test_tensor = torch.tensor([1,1,2,2,3,3])
items, counts = test_tensor.unique(return_counts=True)

new_tensor = torch.tensor([], dtype=torch.int64)
for item, count in zip(items, counts):
    new_tensor = torch.cat((new_tensor, item.repeat(count)))

assert new_tensor.eq(test_tensor).all() # true

You probably want torch.repeat_interleave(). You can use it like this:

 >>> x = torch.tensor([1, 1, 2, 3, 3, 3])
 >>> v, c = torch.unique(x, return_counts=True)
 >>> v, c
 (tensor([1, 2, 3]), tensor([2, 1, 3]))
 
 >>> torch.repeat_interleave(v, c)
 tensor([1, 1, 2, 3, 3, 3])
Related