如何在 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!

那不是推,而是串联。 hcatvcat是二维的特例,但是这里需要第三个,所以更一般的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