我可以将“矩阵”定义为向量的向量。即
vecMat = [[0,1][1,2]]
如果您在 jupyter 笔记本中运行此对象,该对象将被标记为 2 元素
Vector{Vector{Int64}}.
现在如果我这样做了:
newVecMat = eachcol(reduce(hcat,vecMat))
该类型的对象被标记为 2 元素
ColumnSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}
这两者有什么区别? 有什么我应该注意的吗(也许类型不匹配)?
vecMat = [[0,1][1,2]]
无论如何都会出错:
julia> vecMat = [[0,1][1,2]]
ERROR: BoundsError: attempt to access 2-element Vector{Int64} at index [1, 2]
Stacktrace:
[1] getindex(::Vector{Int64}, ::Int64, ::Int64)
@ Base ./essentials.jl:14
这不是创建向量向量的有效语法。你所写的内容得到 2 元素
Vector{Int64}
:
julia> [0,1]
2-element Vector{Int64}:
0
1
并尝试使用
[1,2]
沿二维对其进行索引。
看看这些有效的语法:
julia> x = [[1,2],[3,4]]
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
julia> x = [[1,2];[3,4]]
4-element Vector{Int64}:
1
2
3
4
julia> x = [[1 2],[3 4]]
2-element Vector{Matrix{Int64}}:
[1 2]
[3 4]
julia> x = [[1;2],[3;4]]
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
julia> x = [1 2 3 4]
1×4 Matrix{Int64}:
1 2 3 4
julia> x = [1 2;3 4]
2×2 Matrix{Int64}:
1 2
3 4
Array Literals
的部分应该是一个很好的起点,让您更好地理解这一切的含义:
julia> [1, 2, 3] # A 1-dimensional array (i.e. vector) of `Int`s
3-element Vector{Int64}:
1
2
3
同样,如果参数由制表符、空格或双分号分隔,则它们的内容会“水平连接”在一起。如果方括号内的参数由单个分号 (;) 或换行符而不是逗号分隔,那么它们的内容会“垂直连接”在一起,而不是参数本身用作元素。
可以组合单个分号(或换行符)和空格(或制表符)以同时水平和垂直连接。
空格(和制表符)的优先级高于分号,首先执行任何水平连接,然后连接结果。另一方面,使用双分号进行水平连接会在水平连接结果之前执行任何垂直连接。
...等等。快速阅读一下手册。Julia REPL 具有一个非常有用的功能来学习语言本身:您可以通过键入
?myfunction
?reduce
和
?hcat
。这也记录在手册中,以及启动 REPL 时出现的启动横幅中。同样,对于
eachcol
:
help?> eachcol
search: eachcol eachslice eachmatch
eachcol(A::AbstractVecOrMat) <: AbstractVector
Create a ColumnSlices object that is a vector of columns of matrix or vector A. Column slices are returned as
AbstractVector views of A.
For the inverse, see stack(cols) or reduce(hcat, cols).
See also eachrow, eachslice and mapslices.
│ Julia 1.1
│
│ This function requires at least Julia 1.1.
│ Julia 1.9
│
│ Prior to Julia 1.9, this returned an iterator.
Example
≡≡≡≡≡≡≡
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> s = eachcol(a)
2-element ColumnSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}:
[1, 3]
[2, 4]
help?> ColumnSlices
search: ColumnSlices
ColumnSlices{M,AX,S}
A special case of Slices that is a vector of column slices of a matrix, as constructed by eachcol.
parent can be used to get the underlying matrix.
help?> SubArray
search: SubArray
SubArray{T,N,P,I,L} <: AbstractArray{T,N}
N-dimensional view into a parent array (of type P) with an element type T, restricted by a tuple of indices (of type
I). L is true for types that support fast linear indexing, and false otherwise.
Construct SubArrays using the view function.
另一个有用的工具是
@edit
宏,您可以使用它在您选择的浏览器中打开在评估传递的表达式时将执行的代码。
为
eachcol
执行此操作将带您前往 base/slicearray.jl
来自
Slices
的文档字符串(在源代码中):
在指定维度上将
AbstractArray
切片放入父数组中,返回 viewsXY问题(强调我的),它选择其他维度中的所有数据。
现在您唯一缺少的拼图就是视图。看看手册。
简而言之,切片对象是数组(向量、矩阵等)的包装器,有助于以特定方式迭代数组。例如。 eachcol(M::Matrix)
可以解释为矩阵
M
的列上的迭代器。
切片对象是内存有效的。例如,eachcol(M)
不复制矩阵M
的元素,而是将视图存储到
M
的列。julia> @allocated M = [1 2; 1 2]
96
julia> M
2×2 Matrix{Int64}:
1 2
1 2
julia> @allocated VV = [[1, 1], [2, 2]] # columns of M as vector of vectors
224
julia> VV
2-element Vector{Vector{Int64}}:
[1, 1]
[2, 2]
julia> @allocated EC = eachcol(M) # also columns of M
32
julia> EC
2-element ColumnSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}:
[1, 1]
[2, 2]
julia> EC == VV
true
据了解,标准库中的切片可能无法实现 Array
的某些方法(
Vector
、
Matrix
、...)。虽然切片和 Array
都是 AbstractArrays
的子类型。