首页 > 解决方案 > 如何将数组数组转换为 Julia 中的矩阵?

问题描述

我想将数组数组转换为矩阵。为了显示; 让数组数组为:

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

我想把它变成 3x3 矩阵:

[1 2 3
 4 5 6
 7 8 9]

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

标签: arraysjulia

解决方案


有几种方法可以做到这一点。例如,类似的东西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 运算符...通常在应用于 s 时不会非常有效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 是列优先的。


推荐阅读