줄리아의 범주형 배열

줄리아의 범주형 배열

Categorical Array in julia

개요

줄리아CategoricalArrays.jl 패키지는 R에서의 factor와 비슷한 역할을 한다.

코드

julia> A = ["red", "blue", "red", "green"]
4-element Vector{String}:
 "red"
 "blue"
 "red"
 "green"

julia> B = categorical(A)
4-element CategoricalArray{String,1,UInt32}:
 "red"
 "blue"
 "red"
 "green"

julia> levels(B)
3-element Vector{String}:
 "blue"
 "green"
 "red"

categorical()

categorical() 함수로 일반 배열을 범주형 배열로 캐스트Cast 할 수 있다.

levels()

levels() 함수로는 계급을 볼 수 있다. 당연히 계급엔 중복이 없으며, 배열에서 해당 계급에 해당하는 원소가 없어도 계급 자체는 유지된다.

julia> B[2] = "red"; B
4-element CategoricalArray{String,1,UInt32}:
 "red"
 "red"
 "red"
 "green"

julia> levels(B)
3-element Vector{String}:
 "blue"
 "green"
 "red"

이렇듯 배열의 상태와 관계없이 계급이 유지되는 것은 특정 코딩에서 아주 유용한 특징이 된다. 특히 데이터분석과 관련된 작업에선 데이터셋의 부분집합Subset을 많이 다루게 되는데, 이 때 범주형 배열을 알고 있다면 큰 도움이 될 수 있다.

최적화

굳이 levels()를 쓰지 않고 그냥 일반 배열에서 unique()를 사용해도 비슷한 구현 자체는 된다.

julia> @time for t in 1:10^6
           unique(A)
       end
  0.543157 seconds (6.00 M allocations: 579.834 MiB, 17.33% gc time)

julia> @time for t in 1:10^6
           levels(B)
       end
  0.013324 seconds

그러나 그 속도는 약 40배 정도 차이가 난다. 애초에 배열이 변화할때마다 계급을 업데이트하기 때문에 몇번을 반복하든 따로 계산이랄 걸 거칠 필요 없이 바로 참조할 수 있다.

전체 코드

using CategoricalArrays

A = ["red", "blue", "red", "green"]
B = categorical(A)
levels(B)

B[2] = "red"; B
levels(B)

@time for t in 1:10^6
    unique(A)
end

@time for t in 1:10^6
    levels(B)
end

환경

  • OS: Windows
  • julia: v1.6.3
  • CategoricalArrays v0.10.2
댓글