Search code examples
matrixtuplesjulia

Convert a tuple vector into a matrix in Julia


Let's suppose we have a function, that gives us following:

julia> ExampleFunction(Number1, Number2)
5-element Vector{Tuple{Int64, Int64}}:
 (2, 2)
 (2, 3)
 (3, 3)
 (3, 2)
 (4, 2)

I would like to convert Vector{Tuple{Int64, Int64}} into a matrix, or in my case I would like to convert it into a 5x2 Matrix.


Solution

  • It's not entirely clear from your question how the 5-element vector of tuples of length 2, which has 10 elements in total, should be converted to a 3x2 matrix which holds 6 elements, but assuming that you meant 5x2 here's one way of doing it:

    julia> x = [(1,2), (2, 3), (3, 4)]
    3-element Vector{Tuple{Int64, Int64}}:
     (1, 2)
     (2, 3)
     (3, 4)
    
    julia> hcat(first.(x), last.(x))
    3×2 Matrix{Int64}:
     1  2
     2  3
     3  4
    

    EDIT: As Phips mentioned an alternative below, here's a quick benchmark on Julia 1.7beta3, Windows 10 - I've thrown in a loop version as well, as it always makes sense to try a straightforward loop in Julia:

    julia> convert_to_tuple1(x) = hcat(first.(x), last.(x))
    convert_to_tuple1 (generic function with 1 method)
    
    julia> convert_to_tuple2(x) = PermutedDimsArray(reshape(foldl(append!, x, init = Int[]), 2, :), (2, 1))
    convert_to_tuple2 (generic function with 1 method)
    
    julia> function convert_to_tuple3(x)
               out = Matrix{eltype(x[1])}(undef, length(x), length(x[1]))
               for i ∈ 1:length(x)
                   for j ∈ 1:length(x[1])
                       out[i, j] = x[i][j]
                   end
               end
               out
           end
    convert_to_tuple3 (generic function with 1 method)
    
    julia> xs = [(rand(1:10), rand(1:10)) for _ ∈ 1:1_000_000];
    
    julia> using BenchmarkTools
    
    julia> @btime convert_to_tuple1($xs);
      15.789 ms (6 allocations: 30.52 MiB)
    
    julia> @btime convert_to_tuple2($xs);
      22.067 ms (21 allocations: 18.91 MiB)
    
    julia> @btime convert_to_tuple3($xs);
      7.286 ms (2 allocations: 15.26 MiB)
    

    (further edited to add $ for interpolation of xs into the benchmark)