如何将数组数组转换为 Julia 中的矩阵?

时间:2021-07-13 23:19:51

标签: arrays julia

我想把一个数组数组变成一个矩阵。为了显示;让数组数组为:

[ [1,2,3], [4,5,6], [7,8,9]]

我想把它变成 3x3 矩阵:

[1 2 3
 4 5 6
 7 8 9]

你会如何在 Julia 中做到这一点?

2 个答案:

答案 0 :(得分:4)

有几种方法可以做到这一点。例如,类似于 vcat(transpose.(a)...) 的内容将用作单行

julia> a = [[1,2,3], [4,5,6], [7,8,9]]
3-element Vector{Vector{Int64}}:
 [1, 2, 3]
 [4, 5, 6]
 [7, 8, 9]

julia> vcat(transpose.(a)...)
3×3 Matrix{Int64}:
 1  2  3
 4  5  6
 7  8  9

但请注意

  1. 由于您的内部数组是所写的列向量,因此您需要将它们全部 transpose,然后才能垂直连接(又名 vcat)它们(或者水平连接,然后转置)之后的整个结果,即 transpose(hcat(a...))) 和

  2. 使这种单行工作的 splatting 运算符 ... 通常应用于 Array 时效率不是很高,尤其是应用于更大的数组数组时.

对于较大的数组数组,在性能方面,实际上可能很难击败预先分配正确大小的结果,然后简单地填充一个循环,例如

result = similar(first(a), length(a), length(first(a)))
for i=1:length(a)
    result[i,:] = a[i] # Aside: `=` is actually slightly faster than `.=` here, though either will have the same practical result in this case
end

一些快速基准以供参考:

julia> using BenchmarkTools

julia> @benchmark vcat(transpose.($a)...)
BechmarkTools.Trial: 10000 samples with 405 evaluations.
 Range (min … max):  241.289 ns …   3.994 μs  ┊ GC (min … max): 0.00% … 92.59%
 Time  (median):     262.836 ns               ┊ GC (median):    0.00%
 Time  (mean ± σ):   289.105 ns ± 125.940 ns  ┊ GC (mean ± σ):  2.06% ±  4.61%

  ▁▆▇█▇▆▅▅▅▄▄▄▄▃▂▂▂▃▃▂▂▁▁▁▂▄▃▁▁ ▁                             ▁ ▂
  ████████████████████████████████▇▆▅▆▆▄▆▆▆▄▄▃▅▅▃▄▆▄▁▃▃▃▅▄▁▃▅██ █
  241 ns        Histogram: log(frequency) by time        534 ns <

 Memory estimate: 320 bytes, allocs estimate: 5.

julia> @benchmark for i=1:length($a)
           $result[i,:] = $a[i]
       end
BechmarkTools.Trial: 10000 samples with 993 evaluations.
 Range (min … max):  33.966 ns … 124.918 ns  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     36.710 ns               ┊ GC (median):    0.00%
 Time  (mean ± σ):   39.795 ns ±   7.566 ns  ┊ GC (mean ± σ):  0.00% ± 0.00%

  ▄▄██▄▅▃ ▅▃ ▄▁▂ ▂▁▂▅▂▁    ▄▂▁                                 ▂
  ██████████████▇██████▆█▇▆███▆▇███▇▆▆▅▆▅▅▄▄▅▄▆▆▆▄▁▃▄▁▃▄▅▅▃▁▄█ █
  34 ns         Histogram: log(frequency) by time      77.7 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

通常,逐列填充(如果可能)比我们在此处所做的逐行填充要快,因为 Julia 是列优先的。

答案 1 :(得分:3)

扩展@cbk 的答案,另一个(稍微更有效的)单行是

julia> transpose(reduce(hcat, a))
3×3 transpose(::Matrix{Int64}) with eltype Int64:
 1  2  3
 4  5  6
 7  8  9