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