我想把一个数组数组变成一个矩阵。为了显示;让数组数组为:
[ [1,2,3], [4,5,6], [7,8,9]]
我想把它变成 3x3 矩阵:
[1 2 3
4 5 6
7 8 9]
你会如何在 Julia 中做到这一点?
答案 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
但请注意
由于您的内部数组是所写的列向量,因此您需要将它们全部 transpose
,然后才能垂直连接(又名 vcat
)它们(或者水平连接,然后转置)之后的整个结果,即 transpose(hcat(a...))
) 和
使这种单行工作的 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