Vector 从矩阵切片创建行向量
我想知道是否有人有明确的方法从矩阵的切片返回行向量Vector 从矩阵切片创建行向量,vector,julia,slice,Vector,Julia,Slice,我想知道是否有人有明确的方法从矩阵的切片返回行向量 matrix[k,:] 实际上返回一个大小为(n,)的向量,因此Julia会自动将其视为列向量,而不是行向量。到目前为止,我一直在使用语法 matrix[k,:]' 表示大小为(1,n)的行向量,但不知何故,这看起来很笨拙,而且根本不直观,因为这是行向量而不是列向量。与我交谈过的大多数数学家错误地假设这不是一个行向量 有没有一种更符合儒略的方法来获得更清晰的行向量切片 julia> m=rand(1:10,3,4) 3×4 Array
matrix[k,:]
实际上返回一个大小为(n,)
的向量,因此Julia会自动将其视为列向量,而不是行向量。到目前为止,我一直在使用语法
matrix[k,:]'
表示大小为(1,n)
的行向量,但不知何故,这看起来很笨拙,而且根本不直观,因为这是行向量而不是列向量。与我交谈过的大多数数学家错误地假设这不是一个行向量
有没有一种更符合儒略的方法来获得更清晰的行向量切片
julia> m=rand(1:10,3,4)
3×4 Array{Int64,2}:
4 5 3 9
6 8 1 5
4 5 3 4
julia> m[[1],:]
1×4 Array{Int64,2}:
4 5 3 9
请注意,使用view
s来避免数据复制几乎总是更好的:
julia> @view m[[1],:]
1×4 view(::Array{Int64,2}, [1], :) with eltype Int64:
4 5 3 9
说明:
数组
元素的选择可以通过使用标量或iterables来完成。使用标量会导致删除给定维度。另一方面,使用集合不会删除维度。为了更好的解释,再考虑另一个例子:
julia> m[1:1,1:1]
1×1 Array{Int64,2}:
4
您可以看到,仅选择了一个图元,但未删除尺寸标注。因此,您将得到一个只有一行和一列的矩阵(即二维数组
)
编辑(Colin T Bowers的评论-谢谢!)
决定是否使用视图不是琐事——主要是您的代码是否受益于缓冲。然而,令人惊讶的是,view
s往往更好
julia> const vals = rand(200,200);
julia> using BenchmarkTools
julia> @btime sum(view(vals,1,:))
169.392 ns (1 allocation: 48 bytes)
95.08924081258299
julia> @btime sum(vals[1,:])
184.384 ns (1 allocation: 1.77 KiB)
95.08924081258299
让我们定义我们自己的求和函数
julia> function mysum(a::AbstractVector{A}) where A <: Number
v = zero(A)
@inbounds @simd for i in 1:length(a)
v += a[i]
end
v
end;
julia> @btime mysum(view(vals,1,:))
141.931 ns (0 allocations: 0 bytes)
95.08924081258299
julia> @btime mysum(vals[1,:])
174.934 ns (1 allocation: 1.77 KiB)
95.08924081258297
好极了这正是我想要的。如果你能把m[[1],:]
与m[1,:]
不同的原因添加到你的答案中,我很乐意接受。令人惊讶的是,对于行向量,有时不使用view
要好得多。这是因为Julia中的矩阵是按列主顺序存储的,因此矩阵中的行片在内存中不是连续的。当输入在内存中连续时,许多常见的BLAS操作(如向量求和)都有奇妙的优化,因此,在许多情况下,创建行切片的新副本所浪费的时间被以下事实所抵消:新副本在内存中是连续的,并且可以利用BLAS优化。@NosKnowsAll我根据您的请求添加了解释。@ColinTBowers令人惊讶的是,查看或不查看的决定并不总是那么明显。我的经验是,你每次都需要进行基准测试——请看我的扩展编辑。@PrzemyslawSzufel哇,我并没有要求你添加解释,但你做得很好。完全同意,如果你的日常工作对性能至关重要,那么最好的选择就是基准测试,因为并不总是清楚哪种方法将占主导地位。话虽如此,view
上的sum
性能令人印象深刻,您的优化例程也是如此。我对在v0.3上做这个测试有一个模糊的记忆,在那些日子里,制作一个新的副本显然是赢家。语言已经走过了漫长的道路!
julia> @btime sum(view(vals,:,1))
25.828 ns (1 allocation: 48 bytes)
96.04440265541243
julia> @btime mysum(view(vals,:,1))
13.927 ns (0 allocations: 0 bytes)
96.04440265541243
julia> @btime sum(vals[:,1])
167.745 ns (1 allocation: 1.77 KiB)
96.04440265541243