How to convert Array{Array{Float64, 1}, 1} to Matrix in julia?

前端 未结 2 1193
广开言路
广开言路 2020-12-21 08:45

Let\'s say I have input of this kind:

> [[0.8681299566762923,-0.3472589826095631], [3.2300860990307445,3.3731249077464946]]

How can I co

相关标签:
2条回答
  • 2020-12-21 09:23

    For a general function that will work in most situations, throw an error if there are problems, and allow you to choose the shape of the output matrix, I'm having a hard time coming up with anything smarter than the following (admittedly inelegant looking) solution:

    function toMatrix{T<:Any}(x::Vector{Vector{T}}, dim::Int=1)
        if length(x) == 0
            return(Array(T, 0, 0))
        else
            N = length(x[1])
            M = length(x)
            if dim == 1
                xMat = Array(T, N, M)
                for m = 1:M
                    if length(x[m]) != N
                        error("Conversion not possible due to vector length mismatch")
                    end
                    for n = 1:N
                        xMat[n, m] = x[m][n]
                    end
                end
            elseif dim == 2
                xMat = Array(T, M, N)
                for m = 1:M
                    if length(x[m]) != N
                        error("Conversion not possible due to vector length mismatch")
                    end
                    for n = 1:N
                        xMat[m, n] = x[m][n]
                    end
                end         
            else
                error("Invalid dimension argument")
            end
            return(xMat)
        end
    end
    

    I'll be interested to see what solutions other users can come up with. I'm certainly not aware of a function in Base that does what you're after...

    0 讨论(0)
  • 2020-12-21 09:24

    You can use splatting (...) and hcat to get what you are after:

    julia> a = Vector[[0.8681299566762923,-0.3472589826095631], [3.2300860990307445,3.3731249077464946]]
    2-element Array{Array{T,1},1}:
     [0.8681299566762923,-0.3472589826095631]
     [3.2300860990307445,3.3731249077464946]
    
    julia> hcat(a...)
    2x2 Array{Float64,2}:
      0.86813   3.23009
     -0.347259  3.37312
    

    Or if you wanted stop stack as rows instead of columns you could do the following:

    julia> vcat(map(x->x', a)...)
    2x2 Array{Float64,2}:
     0.86813  -0.347259
     3.23009   3.37312
    

    I don't recommend building a Matrix row by row as that is in conflict with Julia's column major array layout. For larger matrices it is actually more efficient to stack as columns and transpose the output:

    julia> a2 = Vector{Float64}[rand(10) for i=1:5000];
    
    julia> stackrows1{T}(a::Vector{Vector{T}}) = vcat(map(transpose, a)...)::Matrix{T}
    stackrows1 (generic function with 2 methods)
    
    julia> stackrows2{T}(a::Vector{Vector{T}}) = hcat(a...)'::Matrix{T}
    stackrows2 (generic function with 2 methods)
    
    julia> stackrows1(a2) == stackrows2(a2)  # run once to compile and make sure functions do the same thing
    true
    
    julia> @time for i=1:100 stackrows1(a2); end
    elapsed time: 0.142792896 seconds (149 MB allocated, 7.85% gc time in 7 pauses with 0 full sweep)
    
    julia> @time for i=1:100 stackrows2(a2); end
    elapsed time: 0.05213114 seconds (88 MB allocated, 12.60% gc time in 4 pauses with 0 full sweep)
    
    0 讨论(0)
提交回复
热议问题