com.microsoft - Unique#
Unique - 1 (com.microsoft)#
Version
name: Unique (GitHub)
domain: com.microsoft
since_version: 1
function:
support_level:
shape inference:
This version of the operator has been available since version 1 of domain com.microsoft.
Summary
Finds all the unique values (deduped list) present in the given input tensor. This operator returns 3 outputs. The first output tensor ‘uniques’ contains all of the unique elements of the input, sorted in the same order that they occur in the input. The second output tensor ‘idx’ is the same size as the input and it contains the index of each value of the input in ‘uniques’. The third output tensor ‘counts’ contains the count of each element of ‘uniques’ in the input. Example:
input_x = [2, 1, 1, 3, 4, 3] output_uniques = [2, 1, 3, 4] output_idx = [0, 1, 1, 2, 3, 2] output_counts = [1, 2, 2, 1]
Inputs
x (heterogeneous) - T: A 1-D input tensor that is to be processed.
Outputs
y (heterogeneous) - T: A 1-D tensor of the same type as ‘x’ containing all the unique values in ‘x’ sorted in the same order that they occur in the input ‘x’
idx (heterogeneous) - tensor(int64): A 1-D INT64 tensor of the same size as ‘x’ containing the indices for each value in ‘x’ in the output ‘uniques’
counts (heterogeneous) - tensor(int64): A 1-D INT64 tensor containing the the count of each element of ‘uniques’ in the input ‘x’
Examples
_sorted_without_axis
node_sorted = onnx.helper.make_node(
"Unique",
inputs=["X"],
outputs=["Y", "indices", "inverse_indices", "counts"],
)
x = np.array([2.0, 1.0, 1.0, 3.0, 4.0, 3.0], dtype=np.float32)
y, indices, inverse_indices, counts = np.unique(x, True, True, True)
indices, inverse_indices, counts = specify_int64(
indices, inverse_indices, counts
)
expect(
node_sorted,
inputs=[x],
outputs=[y, indices, inverse_indices, counts],
name="test_unique_sorted_without_axis",
)
_not_sorted_without_axis
node_not_sorted = onnx.helper.make_node(
"Unique",
inputs=["X"],
outputs=["Y", "indices", "inverse_indices", "counts"],
sorted=0,
)
# numpy unique does not retain original order (it sorts the output unique values)
# https://github.com/numpy/numpy/issues/8621
# we need to recover unsorted output and indices
x = np.array([2.0, 1.0, 1.0, 3.0, 4.0, 3.0], dtype=np.float32)
y, indices, inverse_indices, counts = np.unique(x, True, True, True)
# prepare index mapping from sorted to unsorted
argsorted_indices = np.argsort(indices)
inverse_indices_map = {
i: si for i, si in zip(argsorted_indices, np.arange(len(argsorted_indices)))
}
indices = indices[argsorted_indices]
y = np.take(x, indices, axis=0)
inverse_indices = np.asarray(
[inverse_indices_map[i] for i in inverse_indices], dtype=np.int64
)
counts = counts[argsorted_indices]
indices, inverse_indices, counts = specify_int64(
indices, inverse_indices, counts
)
# print(y)
# [2.0, 1.0, 3.0, 4.0]
# print(indices)
# [0 1 3 4]
# print(inverse_indices)
# [0, 1, 1, 2, 3, 2]
# print(counts)
# [1, 2, 2, 1]
expect(
node_not_sorted,
inputs=[x],
outputs=[y, indices, inverse_indices, counts],
name="test_unique_not_sorted_without_axis",
)
_sorted_with_axis
node_sorted = onnx.helper.make_node(
"Unique",
inputs=["X"],
outputs=["Y", "indices", "inverse_indices", "counts"],
sorted=1,
axis=0,
)
x = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]], dtype=np.float32)
y, indices, inverse_indices, counts = np.unique(x, True, True, True, axis=0)
indices, inverse_indices, counts = specify_int64(
indices, inverse_indices, counts
)
# print(y)
# [[1. 0. 0.]
# [2. 3. 4.]]
# print(indices)
# [0 2]
# print(inverse_indices)
# [0 0 1]
# print(counts)
# [2 1]
expect(
node_sorted,
inputs=[x],
outputs=[y, indices, inverse_indices, counts],
name="test_unique_sorted_with_axis",
)
_sorted_with_axis_3d
node_sorted = onnx.helper.make_node(
"Unique",
inputs=["X"],
outputs=["Y", "indices", "inverse_indices", "counts"],
sorted=1,
axis=1,
)
x = np.array(
[
[[1.0, 1.0], [0.0, 1.0], [2.0, 1.0], [0.0, 1.0]],
[[1.0, 1.0], [0.0, 1.0], [2.0, 1.0], [0.0, 1.0]],
],
dtype=np.float32,
)
y, indices, inverse_indices, counts = np.unique(x, True, True, True, axis=1)
indices, inverse_indices, counts = specify_int64(
indices, inverse_indices, counts
)
# print(y)
# [[[0. 1.]
# [1. 1.]
# [2. 1.]]
# [[0. 1.]
# [1. 1.]
# [2. 1.]]]
# print(indices)
# [1 0 2]
# print(inverse_indices)
# [1 0 2 0]
# print(counts)
# [2 1 1]
expect(
node_sorted,
inputs=[x],
outputs=[y, indices, inverse_indices, counts],
name="test_unique_sorted_with_axis_3d",
)
_sorted_with_negative_axis
node_sorted = onnx.helper.make_node(
"Unique",
inputs=["X"],
outputs=["Y", "indices", "inverse_indices", "counts"],
sorted=1,
axis=-1,
)
x = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 3]], dtype=np.float32)
y, indices, inverse_indices, counts = np.unique(x, True, True, True, axis=-1)
indices, inverse_indices, counts = specify_int64(
indices, inverse_indices, counts
)
# print(y)
# [[0. 1.]
# [0. 1.]
# [3. 2.]]
# print(indices)
# [1 0]
# print(inverse_indices)
# [1 0 0]
# print(counts)
# [2 1]
expect(
node_sorted,
inputs=[x],
outputs=[y, indices, inverse_indices, counts],
name="test_unique_sorted_with_negative_axis",
)