如何从Julia中的行/列向量构造矩阵

rad*_*ash 2 matrix julia

给定一个产生单个列的函数/表达式,如何从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)

但我发现无法将其转换重塑为我想要的形式(具有两个维度的矩阵而不是数组数组).

如何在朱莉娅实现这一目标?

spe*_*on2 7

你试过了吗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)

  • 如果第二维很大怎么办?当“j”运行到大于 200 万左右的值时,我会出现段错误或堆栈溢出。 (3认同)

GKi*_*GKi 4

由于Julia 1.9.0 stack可用于将一组相同大小的数组(或其他可迭代对象)组合成一个更大的数组,方法是将它们沿一个或多个新维度排列,以便它可用于从行/列构造矩阵向量(从函数/表达式返回)。对于 1.9.0 之前的版本,可以使用 激活using Compat

\n
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\n
Run Code Online (Sandbox Code Playgroud)\n

什么是快速且内存高效的。

\n
using 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\n
Run Code Online (Sandbox Code Playgroud)\n

如果你已经有一个向量。

\n
c = [[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\n
Run Code Online (Sandbox Code Playgroud)\n