【问题标题】:How to convert Array{Array{Float64, 1}, 1} to Matrix in julia?如何在 julia 中将 Array{Array{Float64, 1}, 1} 转换为 Matrix?
【发布时间】:2015-03-20 10:41:48
【问题描述】:

假设我有这样的输入:

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

如何将其转换为更令人愉悦的类型,例如 Matrix(知道维度)?

【问题讨论】:

    标签: julia


    【解决方案1】:

    你可以使用 splatting (...) 和 hcat 来获得你想要的东西:

    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
    

    或者,如果您希望将堆栈停止为行而不是列,您可以执行以下操作:

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

    我不建议逐行构建Matrix,因为这与 Julia 的 column major array layout 冲突。对于较大的矩阵,实际上将其堆叠为列并转置输出效率更高:

    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)
    

    【讨论】:

    • 这比我的方法好多了。 +1
    • 非常感谢,我想出了先扁平化然后使用重塑的解决方案,但它又慢又丑。
    • 使用 Julia 1.0,您可以分别使用 reduce(hcat, x)transpose(reduce(hcat, x)) 获得更好的性能。
    【解决方案2】:

    对于在大多数情况下都可以使用的通用函数,如果有问题会抛出错误,并允许您选择输出矩阵的形状,我很难想出比以下更聪明的东西(诚然看起来不优雅)解决方案:

    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
    

    我很想看看其他用户能想出什么解决方案。我当然不知道Base 中有一个功能可以满足您的需求...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-28
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-09
      相关资源
      最近更新 更多