给定一个产生单个列的函数/表达式,如何从Julia中的那些列构建矩阵?我尝试了以下(简化示例):
column(j) = [j, j, j] # for example
my_matrix = Float64[column(j)[i] for i in 1:3, j in 1:4]
==> 3x4 Array{Float64,2}:
1.0 2.0 3.0 4.0
1.0 2.0 3.0 4.0
1.0 2.0 3.0 4.0
Run Code Online (Sandbox Code Playgroud)
结果是正确的,但这不是我想要的,因为不必要地评估了column-vector-expression(每行一次).
我也尝试过这种替代方法:
[column(j) for j in 1:4]
==> 4-element Array{Array{Float64,1},1}:
[1.0,1.0,1.0]
[2.0,2.0,2.0]
[3.0,3.0,3.0]
[4.0,4.0,4.0]
Run Code Online (Sandbox Code Playgroud)
但我发现无法将其转换或重塑为我想要的形式(具有两个维度的矩阵而不是数组数组).
如何在朱莉娅实现这一目标?
你试过了吗hcat:
julia> column(j) = [j, j ,j]
column (generic function with 1 method)
julia> my_matrix = hcat([column(j) for j=1:4]...)
3x4 Array{Int64,2}:
1 2 3 4
1 2 3 4
1 2 3 4
Run Code Online (Sandbox Code Playgroud)
由于Julia 1.9.0 stack可用于将一组相同大小的数组(或其他可迭代对象)组合成一个更大的数组,方法是将它们沿一个或多个新维度排列,以便它可用于从行/列构造矩阵向量(从函数/表达式返回)。对于 1.9.0 之前的版本,可以使用 激活using Compat。
column(j) = [j, j, j]\n\nstack(column(j) for j=1:4)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\nRun Code Online (Sandbox Code Playgroud)\n什么是快速且内存高效的。
\nusing BenchmarkTools\ncolumn(j) = [j, j, j]\n\n@btime stack(column(j) for j=1:4)\n# 193.315 ns (5 allocations: 480 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime begin #@Beno\xc3\xaet Legat\n m = Matrix{Int}(undef, 3, 4)\n for j in 1:4\n m[:, j] = column(j)\n end\n m\nend\n# 201.942 ns (5 allocations: 480 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime reduce(hcat, [column(j) for j=1:4]) #@Przemyslaw Szufel\n# 249.676 ns (6 allocations: 560 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime reshape(collect(Iterators.flatten([column(j) for j in 1:4])), 3, 4) #@Beno\xc3\xaet Legat\n# 392.325 ns (10 allocations: 976 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime Int[column(j)[i] for i in 1:3, j in 1:4] #@radioflash\n# 440.211 ns (13 allocations: 1.09 KiB)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime hcat([column(j) for j=1:4]...) #@spencerlyon2\n# 644.676 ns (10 allocations: 784 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\nRun Code Online (Sandbox Code Playgroud)\n如果你已经有一个向量。
\nc = [[j,j,j] for j in 1:4]\n#4-element Vector{Vector{Int64}}:\n# [1, 1, 1]\n# [2, 2, 2]\n# [3, 3, 3]\n# [4, 4, 4]\n\nstack(c)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\nusing BenchmarkTools\n\n@btime stack($c)\n# 63.204 ns (1 allocation: 160 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime reduce(hcat, $c) #@Przemyslaw Szufel\n# 68.758 ns (1 allocation: 160 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime begin #@Beno\xc3\xaet Legat\n m = Matrix{Int}(undef, 3, 4)\n for j in 1:4\n m[:, j] = $c[j]\n end\n m\nend\n# 75.586 ns (1 allocation: 160 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime reshape(collect(Iterators.flatten($c)), 3, 4) #@Beno\xc3\xaet Legat\n# 210.752 ns (5 allocations: 576 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\n\n@btime hcat($c...) #@spencerlyon2\n# 453.213 ns (5 allocations: 384 bytes)\n#3\xc3\x974 Matrix{Int64}:\n# 1 2 3 4\n# 1 2 3 4\n# 1 2 3 4\nRun Code Online (Sandbox Code Playgroud)\n