Индексы уникальных элементов вектора в Юлии

Как получить индексы уникальных элементов вектора?

Например, если у вас есть вектор v = [1,2,1,3,5,3], уникальные элементы [1,2,3,5] (вывод unique) и их индексы ind = [1,2,4,5], Какая функция позволяет мне вычислить ind чтобы v[ind] = unique(v)?

4 ответа

Решение

Это решение для Юлии 0.7:

findfirst.(isequal.(unique(x)), [x])

или аналогичные работающие под Julia 0.6.3 и Julia 0.7:

findfirst.(map(a -> (y -> isequal(a, y)), unique(x)), [x])

и более короткая версия (но она не будет работать под Julia 0.7):

findfirst.([x], unique(x))

Это, вероятно, не будет самым быстрым.

Если вам нужна скорость, вы можете написать что-то вроде (должно работать как под Julia 0.7 и 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

Другое предложение

unique(i -> x[i], 1:length(x))

что примерно так же быстро, как функция в принятом ответе (в Julia 1.1), но немного короче.

Если вас не интересует поиск первого индекса для каждого уникального элемента, вы можете использовать комбинацию unique а также indexin функции:

julia> indexin(unique(v), v)
4-element Array{Int64,1}:
 3
 2
 6
 5

Который получает один индекс для каждого уникального элемента v в v, Это все в базе и работает в 0.6. Это примерно в 2,5 раза медленнее, чем функция @Bogumil, но это простая альтернатива.

Смесь ответов Маттсвона и Богумила Камински (спасибо!):

      uniqueidx(v) = unique(i -> v[i], eachindex(v))

eachindexпозволяет работать с любыми массивами , даже с представлениями.

      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)
Другие вопросы по тегам