줄리아에서 배열의 배열을 연결시키는 트릭
개요
줄리아에서는 append!
와 같은 함수를 통해 배열의 배열을 연결시킬 수 있지만, 뱅 컨벤션 !
이 붙은만큼 원래의 배열을 변형시키는 부작용이 있다. 이를 회피하기 위해 스플랫 오퍼레이터 ...
를 사용하는 트릭을 소개한다.
코드
길이가 다른 배열의 배열병합
julia> y = [[3, 1, 4], [1, 5], [9, 2]]
3-element Vector{Vector{Int64}}:
[3, 1, 4]
[1, 5]
[9, 2]
julia> [y...;]
7-element Vector{Int64}:
3
1
4
1
5
9
2
세미콜론 ;
는 배열 y
의 나열 y...
끝에 오는 경우 그 자체로 배열의 병합이 된다. 이는 [y[1]; y[2]; y[3]]
, 더 세련되게는 vcat(x...)
과 같은 결과를 리턴한다.
세로병합 [x...;]
행렬의 차원별로 일치한다면, 행렬 역시 배열의 성질을 가지므로 병합을 하지 못할 이유가 없다. 다차원 병합의 경우 x...
뒤에 붙는 세이콜론의 수 n
에 대해 cat(x..., dims=n)
과 같은 결과를 리턴한다. 이렇게 말로 설명하면 이해하기 어렵고, 구체적인 예시를 통해 확인해 보도록 하자.
julia> x = [reshape(1:4, 2, 2), reshape(5:8, 2, 2), reshape(9:12, 2, 2)];
julia> x[1]
2×2 reshape(::UnitRange{Int64}, 2, 2) with eltype Int64:
1 3
2 4
julia> x[2]
2×2 reshape(::UnitRange{Int64}, 2, 2) with eltype Int64:
5 7
6 8
julia> x[3]
2×2 reshape(::UnitRange{Int64}, 2, 2) with eltype Int64:
9 11
10 12
위와 같이 2차원 배열의 배열이 주어져 있다고 하자.
julia> [x...;]
6×2 Matrix{Int64}:
1 3
2 4
5 7
6 8
9 11
10 12
julia> [x...;] == cat(x..., dims = 1)
true
[x...;]
은 cat(x..., dims = 1)
과 같은 결과로써 행렬을 세로로 병합한 행렬을 리턴한다.
가로병합 [x...;;]
julia> [x...;;]
2×6 Matrix{Int64}:
1 3 5 7 9 11
2 4 6 8 10 12
julia> [x...;;] == cat(x..., dims = 2)
true
[x...;;]
은 ;
이 두 개니까 cat(x..., dims = 2)
과 같은 결과로써 행렬을 가로로 병합한 행렬을 리턴한다.
높이병합 [x...;;;]
julia> [x...;;;]
2×2×3 Array{Int64, 3}:
[:, :, 1] =
1 3
2 4
[:, :, 2] =
5 7
6 8
[:, :, 3] =
9 11
10 12
julia> [x...;;;] == cat(x..., dims = 3)
true
텐서라고 안 될 이유가 없다. [x...;;;]
은 ;
이 세 개니까 cat(x..., dims = 3)
과 같은 결과로써 행렬을 높게 쌓은 텐서를 리턴한다.
전체 코드
y = [[3, 1, 4], [1, 5], [9, 2]]
[y...;]
x = [reshape(1:4, 2, 2), reshape(5:8, 2, 2), reshape(9:12, 2, 2)];
x[1]
x[2]
x[3]
[x...;]
[x...;] == cat(x..., dims = 1)
[x...;;]
[x...;;] == cat(x..., dims = 2)
[x...;;;]
[x...;;;] == cat(x..., dims = 3)
환경
- OS: Windows
- julia: v1.11.1