Reputation: 1905
How to get indexes of unique elements of a vector?
For instance if you have a vector v = [1,2,1,3,5,3]
, the unique elements are [1,2,3,5]
(output of unique
) and their indexes are ind = [1,2,4,5]
. What function allows me to compute ind
so that v[ind] = unique(v)
?
Upvotes: 7
Views: 7966
Reputation: 2509
A mix between mattswon and Bogumił Kamiński answers (thanks !):
uniqueidx(v) = unique(i -> v[i], eachindex(v))
eachindex
allows to work with any kind of array, even views.
julia> v = [1,2,1,3,5,3];
julia> uniqueidx(v)
4-element Vector{Int64}:
1
2
4
5
julia> v2 = reshape(v, 2, 3)
2×3 Matrix{Int64}:
1 1 5
2 3 3
julia> subv2 = view(v2, 1:2, 1:2)
2×2 view(::Matrix{Int64}, 1:2, 1:2) with eltype Int64:
1 1
2 3
julia> uniqueidx(subv2)
3-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(2, 1)
CartesianIndex(2, 2)
Upvotes: 6
Reputation: 111
Another suggestion is
unique(i -> x[i], 1:length(x))
which is about as fast as the function in the accepted answer (in Julia 1.1), but a bit briefer.
Upvotes: 11
Reputation: 5073
If you don't care about finding the first index for each unique element, then you can use a combination of the unique
and indexin
functions:
julia> indexin(unique(v), v)
4-element Array{Int64,1}:
3
2
6
5
Which gets one index for each unique element of v
in v
. These are all in base and works in 0.6. This is about 2.5 times slower than @Bogumil's function, but it's a simple alternative.
Upvotes: 5
Reputation: 69939
This is a solution for Julia 0.7:
findfirst.(isequal.(unique(x)), [x])
or similar working under Julia 0.6.3 and Julia 0.7:
findfirst.(map(a -> (y -> isequal(a, y)), unique(x)), [x])
and a shorter version (but it will not work under Julia 0.7):
findfirst.([x], unique(x))
It will probably not be the fastest.
If you need speed you can write something like (should work both under Julia 0.7 and 0.6.3):
function uniqueidx(x::AbstractArray{T}) where T
uniqueset = Set{T}()
ex = eachindex(x)
idxs = Vector{eltype(ex)}()
for i in ex
xi = x[i]
if !(xi in uniqueset)
push!(idxs, i)
push!(uniqueset, xi)
end
end
idxs
end
Upvotes: 9