假设我们有一个函数,它给了我们以下内容:
julia> ExampleFunction(Number1, Number2)
5-element Vector{Tuple{Int64, Int64}}:
(2, 2)
(2, 3)
(3, 3)
(3, 2)
(4, 2)
我想转换 Vector{Tuple{Int64, Int64}}
转换为矩阵,或者在我的情况下,我想将其转换为 5x2 矩阵。
答案 0 :(得分:3)
从您的问题中并不完全清楚长度为 2 的元组的 5 元素向量(总共有 10 个元素)应如何转换为包含 6 个元素的 3x2 矩阵,但假设您的意思是 5x2,这是一种方法这样做:
julia> x = [(1,2), (2, 3), (3, 4)]
3-element Vector{Tuple{Int64, Int64}}:
(1, 2)
(2, 3)
(3, 4)
julia> hcat(first.(x), last.(x))
3×2 Matrix{Int64}:
1 2
2 3
3 4
编辑:正如 Phips 在下面提到的替代方案,这里是 Julia 1.7beta3、Windows 10 的快速基准测试 - 我也加入了循环版本,因为在 Julia 中尝试直接循环总是有意义的:>
julia> convert_to_tuple1(x) = hcat(first.(x), last.(x))
convert_to_tuple1 (generic function with 1 method)
julia> convert_to_tuple2(x) = PermutedDimsArray(reshape(foldl(append!, x, init = Int[]), 2, :), (2, 1))
convert_to_tuple2 (generic function with 1 method)
julia> function convert_to_tuple3(x)
out = Matrix{eltype(x[1])}(undef, length(x), length(x[1]))
for i ∈ 1:length(x)
for j ∈ 1:length(x[1])
out[i, j] = x[i][j]
end
end
out
end
convert_to_tuple3 (generic function with 1 method)
julia> xs = [(rand(1:10), rand(1:10)) for _ ∈ 1:1_000_000];
julia> using BenchmarkTools
julia> @btime convert_to_tuple1($xs);
15.789 ms (6 allocations: 30.52 MiB)
julia> @btime convert_to_tuple2($xs);
22.067 ms (21 allocations: 18.91 MiB)
julia> @btime convert_to_tuple3($xs);
7.286 ms (2 allocations: 15.26 MiB)
(进一步编辑以添加 $
以将 xs
插值到基准中)
答案 1 :(得分:3)
最快的代码是非复制代码。在另一篇文章的示例中,这会将时间从毫秒减少到纳秒:
julia> xs
1000000-element Vector{Tuple{Int64, Int64}}:
(5, 1)
(4, 3)
⋮
(1, 4)
(9, 2)
julia> @btime reshape(reinterpret(Int, $xs), (2,:))'
10.611 ns (0 allocations: 0 bytes)
1000000×2 adjoint(reshape(reinterpret(Int64, ::Vector{Tuple{Int64, Int64}}), 2, 1000000)) with eltype Int64:
5 1
4 3
⋮
1 4
9 2
对于复制代码来说,最快的将是:
function convert_to_tuple4(x)
out = Matrix{eltype(x[1])}(undef, length(x), length(x[1]))
for i ∈ 1:length(x)
@inbounds @simd for j ∈ 1:length(x[1])
out[i, j] = x[i][j]
end
end
out
end
基准:
julia> @btime convert_to_tuple3($xs);
3.488 ms (2 allocations: 15.26 MiB)
julia> @btime convert_to_tuple4($xs);
2.932 ms (2 allocations: 15.26 MiB)