如何在 julia 中将 Array{Array{Float64, 1}, 1} 转换为 Matrix?
How to convert Array{Array{Float64, 1}, 1} to Matrix in julia?
假设我有这样的输入:
> [[0.8681299566762923,-0.3472589826095631], [3.2300860990307445,3.3731249077464946]]
如何将其转换为更令人愉快的类型,如 Matrix(知道维度)?
对于一个在大多数情况下都能工作的通用函数,如果有问题就抛出一个错误,并允许你选择输出矩阵的形状,我很难想出比以下(诚然看起来不雅)解决方案:
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
中的函数可以满足您的需求...
您可以使用 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)
假设我有这样的输入:
> [[0.8681299566762923,-0.3472589826095631], [3.2300860990307445,3.3731249077464946]]
如何将其转换为更令人愉快的类型,如 Matrix(知道维度)?
对于一个在大多数情况下都能工作的通用函数,如果有问题就抛出一个错误,并允许你选择输出矩阵的形状,我很难想出比以下(诚然看起来不雅)解决方案:
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
中的函数可以满足您的需求...
您可以使用 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)