Jongsu Liam Kim
Jongsu Liam Kim

Reputation: 737

What is the most efficient way to convert 3D array into array of 2D arrays in Julia?

Subject says it all.

I just want to do this, but to me, allocating new array is inefficient.

julia> a = reshape(1:30, 2, 3, 5)

into

julia> b = [a[:, :, i] for i in 1:5]

Is there a simple way to convert type from Array{T, 3} to Array{Array{T, 2}, 1}?

Upvotes: 3

Views: 715

Answers (2)

Jakob Nissen
Jakob Nissen

Reputation: 1991

This is not possible to do without allocating. However, you might be able to use views instead of actually creating the array, e.g. by doing

julia> a = reshape(1:30, 2, 3, 5);

julia> collect(eachslice(a, dims=3))
5-element Array{SubArray{Int64,2,Base.ReshapedArray{Int64,3,UnitRange{Int64},Tuple{}},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},1}:
 [1 3 5; 2 4 6]
 [7 9 11; 8 10 12]
 [13 15 17; 14 16 18]
 [19 21 23; 20 22 24]
 [25 27 29; 26 28 30]

Upvotes: 4

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69919

You can use SplitApplyCombine.jl and there is a function splitdimsview that does exactly what you ask for:

julia> a = reshape(1:30, 2, 3, 5);

julia> b = splitdimsview(a, 3)
5-element SplitDimsArray{SubArray{Int64,2,Base.ReshapedArray{Int64,3,UnitRange{Int64},Tuple{}},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},1,(3,),Base.ReshapedArray{Int64,3,UnitRange{Int64},Tuple{}}}:
 [1 3 5; 2 4 6]
 [7 9 11; 8 10 12]
 [13 15 17; 14 16 18]
 [19 21 23; 20 22 24]
 [25 27 29; 26 28 30]

Note though that the object is not Vector{Matrix} but a custom object (but with the same characteristics except it is a view).

Upvotes: 5

Related Questions