unique() and unique_consecutive() in PyTorch
Tags: pytorch, unique, uniqueconsecutive, function
Published: 2024-04-17 01:35:16

*[Warning]-[unique()](https://pytorch.org/docs/stable/generated/torch.unique.html) and [unique_consecutive()](https://pytorch.org/docs/stable/generated/torch.unique_consecutive.html) are really tricky.

[unique()](https://pytorch.org/docs/stable/generated/torch.unique.html) can get the one or more 1D or more D tensors of zero or more unique elements, their indices and their counts as shown below:  

*Memos:
- `unique()` can be used with [torch](https://pytorch.org/docs/stable/torch.html) or a tensor.
- The 1st argument with `torch` or using a tensor is `input`(Required-Type:`tensor` of `int`, `float` or `bool`).
- The 2nd argument with `torch` or the 1st argument with a tensor is `sorted`(Optional-Default:`True`-Type:`bool`). *Currently setting `False` is also sorted. 
- The 3rd argument with `torch` or the 2nd argument with a tensor is `return_inverse`(Optional-Default:`False`-Type:`bool`). *It returns the indices for where elements in the original input ended up in the returned unique list.
- The 4th argument with `torch` or the 3rd argument with a tensor is `return_counts`(Optional-Default:`False`-Type:`bool`). *It returns the counts for each unique element.
- The 5th argument with `torch` or the 4th argument with a tensor is `dim`(Optional-Type:`int`).

```python
import torch

my_tensor = torch.tensor([[[2, 2, 0], [0, 1, 1]],
                          [[1, 3, 0], [0, 0, 2]]])
torch.unique(input=my_tensor)
my_tensor.unique()
# tensor([0, 1, 2, 3])

torch.unique(input=my_tensor,
             sorted=False,
             return_inverse=True,
             return_counts=True)
# (tensor([0, 1, 2, 3]),
#  tensor([[[2, 2, 0], [0, 1, 1]],
#          [[1, 3, 0], [0, 0, 2]]]),
#  tensor([5, 3, 3, 1]))

torch.unique(input=my_tensor,
             sorted=False,
             return_inverse=True,
             return_counts=True,
             dim=0)
torch.unique(input=my_tensor,
             sorted=False,
             return_inverse=True,
             return_counts=True,
             dim=-3)
# (tensor([[[1, 3, 0], [0, 0, 2]],
#           [[2, 2, 0], [0, 1, 1]]]),
#  tensor([1, 0]),
#  tensor([1, 1]))

torch.unique(input=my_tensor,
             sorted=False,
             return_inverse=True,
             return_counts=True,
             dim=1)
torch.unique(input=my_tensor,
             sorted=False,
             return_inverse=True,
             return_counts=True,
             dim=-2)
# (tensor([[[0, 1, 1], [2, 2, 0]],
#          [[0, 0, 2], [1, 3, 0]]]),
#  tensor([1, 0]),
#  tensor([1, 1]))

torch.unique(input=my_tensor,
             sorted=False,
             return_inverse=True,
             return_counts=True,
             dim=2)
torch.unique(input=my_tensor,
             sorted=False,
             return_inverse=True,
             return_counts=True,
             dim=-1)
# (tensor([[[0, 2, 2], [1, 0, 1]],
#          [[0, 1, 3], [2, 0, 0]]]),
#  tensor([1, 2, 0]),
#  tensor([1, 1, 1]))

my_tensor = torch.tensor([[[2., 2., 0.], [0., 1., 1.]],
                          [[1., 3., 0.], [0., 0., 2.]]])
torch.unique(input=my_tensor)
# tensor([0., 1., 2., 3.])

my_tensor = torch.tensor([[[True, False, True], [True, False, True]],
                          [[False, True, False], [False, True, False]]])
torch.unique(input=my_tensor)
# tensor([False, True])
```

[unique_consecutive()](https://pytorch.org/docs/stable/generated/torch.unique_consecutive.html) can get the zero or more unique elements of a 0D or more D tensor by consecutiveness as shown below:  

*Memos:
- `unique_consecutive()` can be used with `torch` or a tensor.
- The 1st argument with `torch` or using a tensor is `input`(Required-Type:`tensor` of `int`, `float` or `bool`).
- The 2nd argument with `torch` or the 1st argument with a tensor is `return_inverse`(Optional-Default:`False`-Type:`bool`). *It returns the indices for where elements in the original input ended up in the returned unique list.
- The 3rd argument with `torch` or the 2nd argument with a tensor is `return_counts`(Optional-Default:`False`-Type:`bool`). *It returns the counts for each unique element.
- The 4th argument with `torch` or the 3rd argument with a tensor is `dim`(Optional-Type:`int`).
-  `unique_consecutive()` doesn't have `sorted` argument. 

```python
import torch

my_tensor = torch.tensor([[[2, 2, 0], [0, 1, 1]],
                          [[1, 3, 0], [0, 0, 2]]])
torch.unique_consecutive(input=my_tensor)
my_tensor.unique_consecutive()
# tensor([2, 0, 1, 3, 0, 2])

torch.unique_consecutive(input=my_tensor,
                         return_inverse=True,
                         return_counts=True)
# (tensor([2, 0, 1, 3, 0, 2]),
#  tensor([[[0, 0, 1], [1, 2, 2]],
#          [[2, 3, 4], [4, 4, 5]]]),
#  tensor([2, 2, 3, 1, 3, 1]))

torch.unique_consecutive(input=my_tensor,
                         return_inverse=True,
                         return_counts=True,
                         dim=0)
torch.unique_consecutive(input=my_tensor,
                         return_inverse=True,
                         return_counts=True,
                         dim=-3)
# (tensor([[[2, 2, 0], [0, 1, 1]],
#          [[1, 3, 0], [0, 0, 2]]]),
#  tensor([0, 1]),
#  tensor([1, 1]))

torch.unique_consecutive(input=my_tensor,
                         return_inverse=True,
                         return_counts=True,
                         dim=1)
torch.unique_consecutive(my_tensor,
                         return_inverse=True,
                         return_counts=True,
                         dim=-2)
# (tensor([[[2, 2, 0], [0, 1, 1]],
#          [[1, 3, 0], [0, 0, 2]]]),
#  tensor([0, 1]),
#  tensor([1, 1]))

torch.unique_consecutive(input=my_tensor,
                         return_inverse=True,
                         return_counts=True,
                         dim=2)
torch.unique_consecutive(input=my_tensor,
                         return_inverse=True,
                         return_counts=True,
                         dim=-1)
# (tensor([[[2, 2, 0], [0, 1, 1]],
#         [[1, 3, 0], [0, 0, 2]]]),
#  tensor([0, 1, 2]),
#  tensor([1, 1, 1]))

my_tensor = torch.tensor([[[2., 2., 0.], [0., 1., 1.]],
                          [[1., 3., 0.], [0., 0., 2.]]])
torch.unique_consecutive(input=my_tensor)
# tensor([2., 0., 1., 3., 0., 2.])

my_tensor = torch.tensor([[[True, False, True], [True, False, True]],
                          [[False, True, False], [False, True, False]]])
torch.unique_consecutive(input=my_tensor)
# tensor([True, False, True, False, True, False, True, False, True, False])
```