如何在 Julia 中将矩阵推入 3 维数组的给定位置
Hpw to push a matrix into a given position of a 3-dimensional array in Julia
我有矩阵 m
5X5,我想将它推到 3 维数组 me
的第一个 (1) 位置。我在这里做错了什么?
m = rand([0 1 2 3 4 5 6 7 8], 5, 5)
me = zeros(Int, 5, 5, 3)
push!(me[:,:,1], m) # I am doing an error here!
那不是推,而是串联。 hcat
和vcat
是二维的特例,但是这里需要第三个,所以更一般的cat
.
julia> me = reshape(1:(5*5*3), 5, 5, 3);
julia> cat(m, me, dims=3)
5×5×4 Array{Int64, 3}:
[:, :, 1] =
7 5 4 2 8
8 7 7 8 1
3 7 8 7 1
3 8 0 6 4
8 8 6 7 0
[:, :, 2] =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
[:, :, 3] =
26 31 36 41 46
27 32 37 42 47
28 33 38 43 48
29 34 39 44 49
30 35 40 45 50
[:, :, 4] =
51 56 61 66 71
52 57 62 67 72
53 58 63 68 73
54 59 64 69 74
55 60 65 70 75
您不能(有效地)就地执行此操作,因为通常(除了最后一个维度),这相当于在随机位置插入许多单独的内容,而不是很少的移动和复制(我重塑了1:75
形象化)。
使用矩阵数组可能更有效:
julia> me2 = [me[:, :, i] for i in axes(me, 3)]
3-element Vector{Matrix{Int64}}:
[1 6 … 16 21; 2 7 … 17 22; … ; 4 9 … 19 24; 5 10 … 20 25]
[26 31 … 41 46; 27 32 … 42 47; … ; 29 34 … 44 49; 30 35 … 45 50]
[51 56 … 66 71; 52 57 … 67 72; … ; 54 59 … 69 74; 55 60 … 70 75]
julia> pushfirst!(me2, m)
4-element Vector{Matrix{Int64}}:
[7 5 … 2 8; 8 7 … 8 1; … ; 3 8 … 6 4; 8 8 … 7 0]
[1 6 … 16 21; 2 7 … 17 22; … ; 4 9 … 19 24; 5 10 … 20 25]
[26 31 … 41 46; 27 32 … 42 47; … ; 29 34 … 44 49; 30 35 … 45 50]
[51 56 … 66 71; 52 57 … 67 72; … ; 54 59 … 69 74; 55 60 … 70 75]
(主要是理论兴趣)
或者在这种特定情况下,由于您实际使用的是最后一个维度,因此您可以通过处理向量来执行实际的copy/move:
julia> m3 = collect(1:75);
julia> prepend!(m3, m);
julia> A = reshape(m3, 5, 5, :)
5×5×4 Array{Int64, 3}:
[:, :, 1] =
7 5 4 2 8
8 7 7 8 1
3 7 8 7 1
3 8 0 6 4
8 8 6 7 0
[:, :, 2] =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
[:, :, 3] =
26 31 36 41 46
27 32 37 42 47
28 33 38 43 48
29 34 39 44 49
30 35 40 45 50
[:, :, 4] =
51 56 61 66 71
52 57 62 67 72
53 58 63 68 73
54 59 64 69 74
55 60 65 70 75
但现在您可能已经通过共享打开了一堆蠕虫:
julia> prepend!(m3, m)
ERROR: cannot resize array with shared data
Stacktrace:
[1] _growbeg!
@ ./array.jl:946 [inlined]
[2] _prepend!(a::Vector{Int64}, #unused#::Base.HasShape{2}, iter::Matrix{Int64})
@ Base ./array.jl:1123
[3] prepend!(a::Vector{Int64}, iter::Matrix{Int64})
@ Base ./array.jl:1115
[4] top-level scope
@ REPL[101]:1
我有矩阵 m
5X5,我想将它推到 3 维数组 me
的第一个 (1) 位置。我在这里做错了什么?
m = rand([0 1 2 3 4 5 6 7 8], 5, 5)
me = zeros(Int, 5, 5, 3)
push!(me[:,:,1], m) # I am doing an error here!
那不是推,而是串联。 hcat
和vcat
是二维的特例,但是这里需要第三个,所以更一般的cat
.
julia> me = reshape(1:(5*5*3), 5, 5, 3);
julia> cat(m, me, dims=3)
5×5×4 Array{Int64, 3}:
[:, :, 1] =
7 5 4 2 8
8 7 7 8 1
3 7 8 7 1
3 8 0 6 4
8 8 6 7 0
[:, :, 2] =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
[:, :, 3] =
26 31 36 41 46
27 32 37 42 47
28 33 38 43 48
29 34 39 44 49
30 35 40 45 50
[:, :, 4] =
51 56 61 66 71
52 57 62 67 72
53 58 63 68 73
54 59 64 69 74
55 60 65 70 75
您不能(有效地)就地执行此操作,因为通常(除了最后一个维度),这相当于在随机位置插入许多单独的内容,而不是很少的移动和复制(我重塑了1:75
形象化)。
使用矩阵数组可能更有效:
julia> me2 = [me[:, :, i] for i in axes(me, 3)]
3-element Vector{Matrix{Int64}}:
[1 6 … 16 21; 2 7 … 17 22; … ; 4 9 … 19 24; 5 10 … 20 25]
[26 31 … 41 46; 27 32 … 42 47; … ; 29 34 … 44 49; 30 35 … 45 50]
[51 56 … 66 71; 52 57 … 67 72; … ; 54 59 … 69 74; 55 60 … 70 75]
julia> pushfirst!(me2, m)
4-element Vector{Matrix{Int64}}:
[7 5 … 2 8; 8 7 … 8 1; … ; 3 8 … 6 4; 8 8 … 7 0]
[1 6 … 16 21; 2 7 … 17 22; … ; 4 9 … 19 24; 5 10 … 20 25]
[26 31 … 41 46; 27 32 … 42 47; … ; 29 34 … 44 49; 30 35 … 45 50]
[51 56 … 66 71; 52 57 … 67 72; … ; 54 59 … 69 74; 55 60 … 70 75]
(主要是理论兴趣)
或者在这种特定情况下,由于您实际使用的是最后一个维度,因此您可以通过处理向量来执行实际的copy/move:
julia> m3 = collect(1:75);
julia> prepend!(m3, m);
julia> A = reshape(m3, 5, 5, :)
5×5×4 Array{Int64, 3}:
[:, :, 1] =
7 5 4 2 8
8 7 7 8 1
3 7 8 7 1
3 8 0 6 4
8 8 6 7 0
[:, :, 2] =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
[:, :, 3] =
26 31 36 41 46
27 32 37 42 47
28 33 38 43 48
29 34 39 44 49
30 35 40 45 50
[:, :, 4] =
51 56 61 66 71
52 57 62 67 72
53 58 63 68 73
54 59 64 69 74
55 60 65 70 75
但现在您可能已经通过共享打开了一堆蠕虫:
julia> prepend!(m3, m)
ERROR: cannot resize array with shared data
Stacktrace:
[1] _growbeg!
@ ./array.jl:946 [inlined]
[2] _prepend!(a::Vector{Int64}, #unused#::Base.HasShape{2}, iter::Matrix{Int64})
@ Base ./array.jl:1123
[3] prepend!(a::Vector{Int64}, iter::Matrix{Int64})
@ Base ./array.jl:1115
[4] top-level scope
@ REPL[101]:1