Arrays
Constructors and Types
Core.AbstractArray
— TypeAbstractArray{T,N}
N
维数组(或类似数组的类型)的超类型,其元素类型为T
。Array
和其他类型是其子类型。请参阅手册中关于AbstractArray
接口的部分。
Base.AbstractVector
— TypeAbstractVector{T}
一维数组(或类似数组的类型)的超类型,其元素类型为 T
。是 AbstractArray{T,1}
的别名。
Base.AbstractMatrix
— TypeAbstractMatrix{T}
二维数组(或类似数组的类型)的超类型,其元素类型为 T
。是 AbstractArray{T,2}
的别名。
Base.AbstractVecOrMat
— TypeAbstractVecOrMat{T}
AbstractVector{T}
和 AbstractMatrix{T}
的联合类型。
Core.Array
— TypeArray{T,N} <: AbstractArray{T,N}
具有类型 T
的 N
维稠密数组。
Core.Array
— MethodArray{T}(undef, dims)
Array{T,N}(undef, dims)
构造一个未初始化的 N
维 Array
,其元素类型为 T
。N
可以显式提供,如 Array{T,N}(undef, dims)
,或者通过 dims
的长度或数量来确定。dims
可以是一个元组或一系列整数参数,对应于每个维度的长度。如果显式提供了秩 N
,则它必须与 dims
的长度或数量匹配。这里 undef
是 UndefInitializer
。
示例
julia> A = Array{Float64, 2}(undef, 2, 3) # N 显式给出
2×3 Matrix{Float64}:
6.90198e-310 6.90198e-310 6.90198e-310
6.90198e-310 6.90198e-310 0.0
julia> B = Array{Float64}(undef, 4) # N 由输入确定
4-element Vector{Float64}:
2.360075077e-314
NaN
2.2671131793e-314
2.299821756e-314
julia> similar(B, 2, 4, 1) # 使用 typeof(B),以及给定的大小
2×4×1 Array{Float64, 3}:
[:, :, 1] =
2.26703e-314 2.26708e-314 0.0 2.80997e-314
0.0 2.26703e-314 2.26708e-314 0.0
Core.Array
— MethodArray{T}(nothing, dims)
Array{T,N}(nothing, dims)
构造一个 N
维的 Array
,包含类型为 T
的元素,初始化为 nothing
条目。元素类型 T
必须能够容纳这些值,即 Nothing <: T
。
示例
julia> Array{Union{Nothing, String}}(nothing, 2)
2-element Vector{Union{Nothing, String}}:
nothing
nothing
julia> Array{Union{Nothing, Int}}(nothing, 2, 3)
2×3 Matrix{Union{Nothing, Int64}}:
nothing nothing nothing
nothing nothing nothing
Core.Array
— MethodArray{T}(missing, dims)
Array{T,N}(missing, dims)
构造一个 N
维的 Array
,包含类型为 T
的元素,初始化为 missing
条目。元素类型 T
必须能够容纳这些值,即 Missing <: T
。
示例
julia> Array{Union{Missing, String}}(missing, 2)
2-element Vector{Union{Missing, String}}:
missing
missing
julia> Array{Union{Missing, Int}}(missing, 2, 3)
2×3 Matrix{Union{Missing, Int64}}:
missing missing missing
missing missing missing
Core.UndefInitializer
— TypeUndefInitializer
单例类型用于数组初始化,表示数组构造函数调用者希望得到一个未初始化的数组。另见 undef
,它是 UndefInitializer()
的别名。
示例
julia> Array{Float64, 1}(UndefInitializer(), 3)
3-element Array{Float64, 1}:
2.2752528595e-314
2.202942107e-314
2.275252907e-314
Core.undef
— Constantundef
UndefInitializer()
的别名,它构造了单例类型 UndefInitializer
的实例,用于数组初始化,以指示数组构造调用者希望得到一个未初始化的数组。
示例
julia> Array{Float64, 1}(undef, 3)
3-element Vector{Float64}:
2.2752528595e-314
2.202942107e-314
2.275252907e-314
Base.Vector
— TypeVector{T} <: AbstractVector{T}
一维稠密数组,元素类型为 T
,通常用于表示数学向量。是 Array{T,1}
的别名。
Base.Vector
— MethodVector{T}(undef, n)
构造一个长度为 n
的未初始化 Vector{T}
。
示例
julia> Vector{Float64}(undef, 3)
3-element Array{Float64, 1}:
6.90966e-310
6.90966e-310
6.90966e-310
Base.Vector
— MethodVector{T}(nothing, m)
构造一个 Vector{T}
,长度为 m
,初始化为 nothing
条目。元素类型 T
必须能够容纳这些值,即 Nothing <: T
。
示例
julia> Vector{Union{Nothing, String}}(nothing, 2)
2-element Vector{Union{Nothing, String}}:
nothing
nothing
Base.Vector
— MethodVector{T}(missing, m)
构造一个 Vector{T}
,长度为 m
,初始化为 missing
条目。元素类型 T
必须能够容纳这些值,即 Missing <: T
。
示例
julia> Vector{Union{Missing, String}}(missing, 2)
2-element Vector{Union{Missing, String}}:
missing
missing
Base.Matrix
— TypeMatrix{T} <: AbstractMatrix{T}
具有类型 T
的二维稠密数组,通常用于表示数学矩阵。是 Array{T,2}
的别名。
Base.Matrix
— MethodMatrix{T}(undef, m, n)
构造一个未初始化的 Matrix{T}
,大小为 m
×n
。
示例
julia> Matrix{Float64}(undef, 2, 3)
2×3 Array{Float64, 2}:
2.36365e-314 2.28473e-314 5.0e-324
2.26704e-314 2.26711e-314 NaN
julia> similar(ans, Int32, 2, 2)
2×2 Matrix{Int32}:
490537216 1277177453
1 1936748399
Base.Matrix
— MethodMatrix{T}(nothing, m, n)
构造一个 Matrix{T}
,大小为 m
×n
,初始化为 nothing
条目。元素类型 T
必须能够容纳这些值,即 Nothing <: T
。
示例
julia> Matrix{Union{Nothing, String}}(nothing, 2, 3)
2×3 Matrix{Union{Nothing, String}}:
nothing nothing nothing
nothing nothing nothing
Base.Matrix
— MethodMatrix{T}(missing, m, n)
构造一个 Matrix{T}
,大小为 m
×n
,初始化为 missing
条目。元素类型 T
必须能够容纳这些值,即 Missing <: T
。
示例
julia> Matrix{Union{Missing, String}}(missing, 2, 3)
2×3 Matrix{Union{Missing, String}}:
missing missing missing
missing missing missing
Base.VecOrMat
— TypeVecOrMat{T}
联合类型 Vector{T}
和 Matrix{T}
,允许函数接受矩阵或向量。
示例
julia> Vector{Float64} <: VecOrMat{Float64}
true
julia> Matrix{Float64} <: VecOrMat{Float64}
true
julia> Array{Float64, 3} <: VecOrMat{Float64}
false
Core.DenseArray
— TypeDenseArray{T, N} <: AbstractArray{T,N}
N
维稠密数组,元素类型为 T
。稠密数组的元素在内存中连续存储。
Base.DenseVector
— TypeDenseVector{T}
一维 DenseArray
,元素类型为 T
。是 DenseArray{T,1}
的别名。
Base.DenseMatrix
— TypeDenseMatrix{T}
具有类型 T
的二维 DenseArray
。DenseArray{T,2}
的别名。
Base.DenseVecOrMat
— TypeDenseVecOrMat{T}
DenseVector{T}
和 DenseMatrix{T}
的联合类型。
Base.StridedArray
— TypeStridedArray{T, N}
一个硬编码的 Union
常见数组类型的集合,遵循 分步数组接口,元素类型为 T
,维度为 N
。
如果 A
是一个 StridedArray
,那么它的元素在内存中是以偏移量存储的,这些偏移量在不同维度之间可能会有所不同,但在同一维度内是恒定的。例如,A
在维度 1 上的步幅可能为 2,在维度 2 上的步幅可能为 3。沿着维度 d
增加 A
时,内存中的跳跃量为 [stride(A, d)
] 个槽位。分步数组特别重要且有用,因为它们有时可以直接作为指针传递给像 BLAS 这样的外部语言库。
Base.StridedVector
— TypeStridedVector{T}
一维 StridedArray
,元素类型为 T
。
Base.StridedMatrix
— TypeStridedMatrix{T}
具有类型 T
的元素的二维 StridedArray
。
Base.StridedVecOrMat
— TypeStridedVecOrMat{T}
类型 T
的 StridedVector
和 StridedMatrix
的联合类型。
Core.GenericMemory
— TypeGenericMemory{kind::Symbol, T, addrspace=Core.CPU} <: DenseVector{T}
固定大小的 DenseVector{T}
。
kind
目前可以是 :not_atomic
或 :atomic
。有关 :atomic
的详细信息,请参见 AtomicMemory
addrspace
目前只能设置为 Core.CPU。它旨在允许其他系统(例如 GPU)的扩展,这些系统可能定义如下值:
module CUDA
const Generic = bitcast(Core.AddrSpace{CUDA}, 0)
const Global = bitcast(Core.AddrSpace{CUDA}, 1)
end
这些其他地址空间的确切语义由特定的后端定义,但如果用户试图在 CPU 上访问这些地址空间,将会出错。
此类型需要 Julia 1.11 或更高版本。
Core.Memory
— TypeMemory{T} == GenericMemory{:not_atomic, T, Core.CPU}
固定大小的 DenseVector{T}
。
!!! 兼容性 "Julia 1.11" 此类型需要 Julia 1.11 或更高版本。
Core.memoryref
— Function`memoryref(::GenericMemory)`
从内存对象构造一个 GenericMemoryRef
。这不会失败,但结果内存仅在内存为空时指向越界。
memoryref(::GenericMemory, index::Integer)
memoryref(::GenericMemoryRef, index::Integer)
从内存对象和一个偏移索引(基于1的索引,可以是负数)构造一个 GenericMemoryRef
。这总是返回一个有效的对象,如果不可能(因为索引会导致超出基础内存的范围),则会抛出错误。
Base.Slices
— TypeSlices{P,SM,AX,S,N} <: AbstractSlices{S,N}
一个 AbstractArray
,用于在指定维度上对父数组进行切片,返回从其他维度选择所有数据的视图。
这些通常应通过 eachslice
、eachcol
或 eachrow
构造。
parent(s::Slices)
将返回父数组。
Base.RowSlices
— TypeBase.ColumnSlices
— TypeBase.getindex
— Methodgetindex(type[, elements...])
构造指定类型的一维数组。通常使用语法 Type[]
调用。元素值可以使用 Type[a,b,c,...]
指定。
示例
julia> Int8[1, 2, 3]
3-element Vector{Int8}:
1
2
3
julia> getindex(Int8, 1, 2, 3)
3-element Vector{Int8}:
1
2
3
Base.zeros
— Functionzeros([T=Float64,] dims::Tuple)
zeros([T=Float64,] dims...)
创建一个元素类型为 T
的数组,所有元素为零,大小由 dims
指定。另见 fill
, ones
, zero
。
示例
julia> zeros(1)
1-element Vector{Float64}:
0.0
julia> zeros(Int8, 2, 3)
2×3 Matrix{Int8}:
0 0 0
0 0 0
Base.ones
— Functionones([T=Float64,] dims::Tuple)
ones([T=Float64,] dims...)
创建一个元素类型为 T
的 Array
,其大小由 dims
指定,所有元素均为一。另见 fill
,zeros
。
示例
julia> ones(1,2)
1×2 Matrix{Float64}:
1.0 1.0
julia> ones(ComplexF64, 2, 3)
2×3 Matrix{ComplexF64}:
1.0+0.0im 1.0+0.0im 1.0+0.0im
1.0+0.0im 1.0+0.0im 1.0+0.0im
Base.BitArray
— TypeBitArray{N} <: AbstractArray{Bool, N}
节省空间的 N
维布尔数组,每个布尔值仅使用一个比特。
BitArray
将最多 64 个值打包到每 8 字节中,导致相对于 Array{Bool, N}
的 8 倍空间效率,并允许某些操作一次处理 64 个值。
默认情况下,Julia 从生成布尔元素的 broadcasting 操作(包括像 .==
这样的点比较)以及从函数 trues
和 falses
返回 BitArrays
。
由于其打包存储格式,BitArray
的元素的并发访问(其中至少有一个是写入)不是线程安全的。
Base.BitArray
— MethodBitArray(undef, dims::Integer...)
BitArray{N}(undef, dims::NTuple{N,Int})
构造一个未定义的 BitArray
,具有给定的维度。行为与 Array
构造函数完全相同。参见 undef
。
示例
julia> BitArray(undef, 2, 2)
2×2 BitMatrix:
0 0
0 0
julia> BitArray(undef, (3, 1))
3×1 BitMatrix:
0
0
0
Base.BitArray
— MethodBitArray(itr)
构造一个由给定可迭代对象生成的 BitArray
。形状由 itr
对象推断得出。
示例
julia> BitArray([1 0; 0 1])
2×2 BitMatrix:
1 0
0 1
julia> BitArray(x+y == 3 for x = 1:2, y = 1:3)
2×3 BitMatrix:
0 1 0
1 0 0
julia> BitArray(x+y == 3 for x = 1:2 for y = 1:3)
6-element BitVector:
0
1
0
1
0
0
Base.trues
— Functiontrues(dims)
创建一个所有值都设置为 true
的 BitArray
。
示例
julia> trues(2,3)
2×3 BitMatrix:
1 1 1
1 1 1
Base.falses
— Functionfalses(dims)
创建一个所有值都设置为 false
的 BitArray
。
示例
julia> falses(2,3)
2×3 BitMatrix:
0 0 0
0 0 0
Base.fill
— Functionfill(value, dims::Tuple)
fill(value, dims...)
创建一个大小为 dims
的数组,所有位置都设置为 value
。
例如,fill(1.0, (5,5))
返回一个 5×5 的浮点数组,数组的每个位置都为 1.0
。
维度长度 dims
可以指定为元组或参数序列。一个 N
长度的元组或跟在 value
后面的 N
个参数指定一个 N
维数组。因此,创建一个零维数组并将其唯一位置设置为 x
的常见习惯用法是 fill(x)
。
返回数组的每个位置都设置为(因此是 ===
)传入的 value
;这意味着如果 value
本身被修改,所有填充的数组元素都会反映该修改,因为它们仍然是那个 value
。对于 fill(1.0, (5,5))
来说,这没有问题,因为 value
1.0
是不可变的,无法被修改,但对于可变值(如最常见的数组)来说,这可能会出乎意料。例如,fill([], 3)
将同一个空数组放在返回向量的所有三个位置:
julia> v = fill([], 3)
3-element Vector{Vector{Any}}:
[]
[]
[]
julia> v[1] === v[2] === v[3]
true
julia> value = v[1]
Any[]
julia> push!(value, 867_5309)
1-element Vector{Any}:
8675309
julia> v
3-element Vector{Vector{Any}}:
[8675309]
[8675309]
[8675309]
要创建多个独立的内部数组,请使用 comprehension。这会在循环的每次迭代中创建一个新的独立数组:
julia> v2 = [[] for _ in 1:3]
3-element Vector{Vector{Any}}:
[]
[]
[]
julia> v2[1] === v2[2] === v2[3]
false
julia> push!(v2[1], 8675309)
1-element Vector{Any}:
8675309
julia> v2
3-element Vector{Vector{Any}}:
[8675309]
[]
[]
另请参见: fill!
, zeros
, ones
, similar
.
示例
julia> fill(1.0, (2,3))
2×3 Matrix{Float64}:
1.0 1.0 1.0
1.0 1.0 1.0
julia> fill(42)
0-dimensional Array{Int64, 0}:
42
julia> A = fill(zeros(2), 2) # 将两个元素设置为相同的 [0.0, 0.0] 向量
2-element Vector{Vector{Float64}}:
[0.0, 0.0]
[0.0, 0.0]
julia> A[1][1] = 42; # 将填充的值修改为 [42.0, 0.0]
julia> A # A[1] 和 A[2] 是同一个向量
2-element Vector{Vector{Float64}}:
[42.0, 0.0]
[42.0, 0.0]
Base.fill!
— Functionfill!(A, x)
用值 x
填充数组 A
。如果 x
是对象引用,则所有元素将引用同一个对象。fill!(A, Foo())
将返回用一次评估 Foo()
的结果填充的 A
。
示例
julia> A = zeros(2,3)
2×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0
julia> fill!(A, 2.)
2×3 Matrix{Float64}:
2.0 2.0 2.0
2.0 2.0 2.0
julia> a = [1, 1, 1]; A = fill!(Vector{Vector{Int}}(undef, 3), a); a[1] = 2; A
3-element Vector{Vector{Int64}}:
[2, 1, 1]
[2, 1, 1]
[2, 1, 1]
julia> x = 0; f() = (global x += 1; x); fill!(Vector{Int}(undef, 3), f())
3-element Vector{Int64}:
1
1
1
Base.empty
— Functionempty(x::Tuple)
返回一个空元组,()
。
empty(v::AbstractVector, [eltype])
创建一个与 v
类似的空向量,选项上可以更改 eltype
。
另见: empty!
, isempty
, isassigned
。
示例
julia> empty([1.0, 2.0, 3.0])
Float64[]
julia> empty([1.0, 2.0, 3.0], String)
String[]
empty(a::AbstractDict, [index_type=keytype(a)], [value_type=valtype(a)])
创建一个空的 AbstractDict
容器,可以接受类型为 index_type
的索引和类型为 value_type
的值。第二个和第三个参数是可选的,默认为输入的 keytype
和 valtype
,分别。(如果只指定了两种类型中的一种,则假定为 value_type
,而 index_type
默认为 keytype(a)
)。
自定义的 AbstractDict
子类型可以选择最适合给定索引和值类型的特定字典类型,通过对三参数签名进行特化。默认情况下返回一个空的 Dict
。
Base.similar
— Functionsimilar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}
创建一个未初始化的可变数组,具有给定的元素类型、索引类型和大小,基于给定的源 SparseMatrixCSC
。新的稀疏矩阵保持原始稀疏矩阵的结构,除非输出矩阵的维度与输出不同。
输出矩阵在与输入相同的位置上有零,但在非零位置上有未初始化的值。
similar(array, [element_type=eltype(array)], [dims=size(array)])
创建一个未初始化的可变数组,其元素类型和大小基于给定的源数组。第二个和第三个参数都是可选的,默认为给定数组的 eltype
和 size
。维度可以作为单个元组参数或一系列整数参数来指定。
自定义的 AbstractArray 子类型可以选择哪种特定的数组类型最适合返回给定的元素类型和维度。如果它们不专门化此方法,默认返回的是 Array{element_type}(undef, dims...)
。
例如,similar(1:10, 1, 4)
返回一个未初始化的 Array{Int,2}
,因为范围既不可变也不支持 2 维:
julia> similar(1:10, 1, 4)
1×4 Matrix{Int64}:
4419743872 4374413872 4419743888 0
相反,similar(trues(10,10), 2)
返回一个未初始化的 BitVector
,其中有两个元素,因为 BitArray
既可变又可以支持 1 维数组:
julia> similar(trues(10,10), 2)
2-element BitVector:
0
0
然而,由于 BitArray
只能存储 Bool
类型的元素,如果请求不同的元素类型,它将创建一个常规的 Array
:
julia> similar(falses(10), Float64, 2, 4)
2×4 Matrix{Float64}:
2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314
2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314
另请参见: undef
, isassigned
.
similar(storagetype, axes)
创建一个未初始化的可变数组,类似于由 storagetype
指定的数组,但其维度由最后一个参数 axes
指定。
示例:
similar(Array{Int}, axes(A))
创建一个“像” Array{Int}
的数组(并且可能确实由一个支持),但其索引与 A
相同。如果 A
具有常规索引,这将与 Array{Int}(undef, size(A))
相同,但如果 A
具有非常规索引,则结果的索引将与 A
匹配。
similar(BitArray, (axes(A, 2),))
将创建一个一维逻辑数组,其索引与 A
的列相匹配。
Basic functions
Base.ndims
— Functionndims(A::AbstractArray) -> Integer
返回 A
的维数。
示例
julia> A = fill(1, (3,4,5));
julia> ndims(A)
3
Base.size
— Functionsize(A::AbstractArray, [dim])
返回一个包含 A
维度的元组。您可以选择指定一个维度以仅获取该维度的长度。
请注意,对于具有非标准索引的数组,size
可能未定义,在这种情况下 axes
可能会很有用。请参阅手册中关于 具有自定义索引的数组 的章节。
另请参见:length
, ndims
, eachindex
, sizeof
。
示例
julia> A = fill(1, (2,3,4));
julia> size(A)
(2, 3, 4)
julia> size(A, 2)
3
Base.axes
— Methodaxes(A)
返回数组 A
的有效索引元组。
示例
julia> A = fill(1, (5,6,7));
julia> axes(A)
(Base.OneTo(5), Base.OneTo(6), Base.OneTo(7))
Base.axes
— Methodaxes(A, d)
返回数组 A
在维度 d
上的有效索引范围。
另见 size
,以及关于 具有自定义索引的数组 的手册章节。
示例
julia> A = fill(1, (5,6,7));
julia> axes(A, 2)
Base.OneTo(6)
julia> axes(A, 4) == 1:1 # 所有维度 d > ndims(A) 的大小为 1
true
使用说明
每个索引必须是 AbstractUnitRange{<:Integer}
,但同时可以是使用自定义索引的类型。因此,例如,如果您需要一个子集,请使用诸如 begin
/end
或 firstindex
/lastindex
的广义索引构造:
ix = axes(v, 1)
ix[2:end] # 对于例如 Vector 会有效,但在一般情况下可能会失败
ix[(begin+1):end] # 对于广义索引有效
Base.length
— Methodlength(A::AbstractArray)
返回数组中的元素数量,默认为 prod(size(A))
。
示例
julia> length([1, 2, 3, 4])
4
julia> length([1 2; 3 4])
4
Base.keys
— Methodkeys(a::AbstractArray)
返回一个有效索引的高效数组,描述 a
的所有有效索引,并按照 a
本身的形状排列。
一维数组(向量)的键是整数,而所有其他 N 维数组使用 CartesianIndex
来描述它们的位置。通常,特殊数组类型 LinearIndices
和 CartesianIndices
被用来高效地表示这些整数和 CartesianIndex
的数组。
请注意,数组的 keys
可能不是最有效的索引类型;为了获得最佳性能,请使用 eachindex
替代。
示例
julia> keys([4, 5, 6])
3-element LinearIndices{1, Tuple{Base.OneTo{Int64}}}:
1
2
3
julia> keys([4 5; 6 7])
CartesianIndices((2, 2))
Base.eachindex
— Functioneachindex(A...)
eachindex(::IndexStyle, A::AbstractArray...)
创建一个可迭代对象,以高效的方式访问 AbstractArray
A
的每个索引。对于选择快速线性索引的数组类型(如 Array
),这仅仅是范围 1:length(A)
,如果它们使用的是基于1的索引。对于未选择快速线性索引的数组类型,通常返回一个专门的笛卡尔范围,以便使用为每个维度指定的索引高效地索引数组。
一般来说,eachindex
接受任意可迭代对象,包括字符串和字典,并返回一个支持任意索引类型(例如不均匀间隔或非整数索引)的迭代器对象。
如果 A
是 AbstractArray
,可以通过将一个具有 IndexStyle
类型的值作为第一个参数显式指定 eachindex
应返回的索引样式(通常如果需要线性索引则为 IndexLinear()
,如果想要笛卡尔范围则为 IndexCartesian()
)。
如果您提供多个 AbstractArray
参数,eachindex
将创建一个对所有参数都快速的可迭代对象(通常如果所有输入都有快速线性索引,则为 UnitRange
,否则为 CartesianIndices
)。如果数组的大小和/或维度不同,将抛出 DimensionMismatch
异常。
另请参见 pairs
(A)
以同时迭代索引和值,以及 axes
(A, 2)
以获取沿一个维度的有效索引。
示例
julia> A = [10 20; 30 40];
julia> for i in eachindex(A) # 线性索引
println("A[", i, "] == ", A[i])
end
A[1] == 10
A[2] == 30
A[3] == 20
A[4] == 40
julia> for i in eachindex(view(A, 1:2, 1:1)) # 笛卡尔索引
println(i)
end
CartesianIndex(1, 1)
CartesianIndex(2, 1)
Base.IndexStyle
— TypeIndexStyle(A)
IndexStyle(typeof(A))
IndexStyle
指定了数组 A
的“原生索引风格”。当你定义一个新的 AbstractArray
类型时,你可以选择实现线性索引(使用 IndexLinear
)或笛卡尔索引。如果你决定只实现线性索引,那么你必须为你的数组类型设置这个特性:
Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()
默认值是 IndexCartesian()
。
Julia 的内部索引机制将自动(并且隐式地)将所有索引操作重新计算为首选风格。这允许用户使用任何索引风格访问你的数组元素,即使没有提供显式的方法。
如果你为你的 AbstractArray
定义了两种索引风格,这个特性可以用来选择性能最优的索引风格。一些方法会检查其输入上的这个特性,并根据最有效的访问模式调度到不同的算法。特别是,eachindex
创建一个迭代器,其类型取决于这个特性的设置。
Base.IndexLinear
— TypeIndexLinear()
IndexStyle
的子类型,用于描述通过一个线性索引最佳索引的数组。
线性索引样式使用一个整数索引来描述数组中的位置(即使它是一个多维数组),并使用列主序来高效访问元素。这意味着从一个 IndexLinear
的数组请求 eachindex
将返回一个简单的一维范围,即使它是多维的。
一个报告其 IndexStyle
为 IndexLinear
的自定义数组只需要实现使用单个 Int
索引的索引(和索引赋值);所有其他索引表达式——包括多维访问——将被重新计算为线性索引。例如,如果 A
是一个 2×3
的自定义矩阵并使用线性索引,当我们引用 A[1, 3]
时,这将被重新计算为等效的线性索引并调用 A[5]
,因为 1 + 2*(3 - 1) = 5
。
另见 IndexCartesian
。
Base.IndexCartesian
— TypeIndexCartesian()
IndexStyle
的子类型,用于描述通过笛卡尔索引最佳索引的数组。这是新自定义 AbstractArray
子类型的默认值。
笛卡尔索引样式使用多个整数索引来描述多维数组中的位置,每个维度恰好一个索引。这意味着从 IndexCartesian
的数组请求 eachindex
将返回一系列 CartesianIndices
。
一个报告其 IndexStyle
为 IndexCartesian
的 N
维自定义数组需要使用恰好 N
个 Int
索引来实现索引(和索引赋值);所有其他索引表达式——包括线性索引——将被重新计算为等效的笛卡尔位置。例如,如果 A
是一个具有笛卡尔索引的 2×3
自定义矩阵,而我们引用 A[5]
,这将被重新计算为等效的笛卡尔索引并调用 A[1, 3]
,因为 5 = 1 + 2*(3 - 1)
。
从线性索引计算笛卡尔索引的成本显著高于反向计算。前者操作需要除法——这是一个非常昂贵的操作——而后者仅使用乘法和加法,基本上是免费的。这种不对称意味着在 IndexCartesian
数组中使用线性索引的成本远高于在 IndexLinear
数组中使用笛卡尔索引的成本。
另见 IndexLinear
。
Base.conj!
— Functionconj!(A)
将数组转换为其复共轭,原地修改。
另见 conj
。
示例
julia> A = [1+im 2-im; 2+2im 3+im]
2×2 Matrix{Complex{Int64}}:
1+1im 2-1im
2+2im 3+1im
julia> conj!(A);
julia> A
2×2 Matrix{Complex{Int64}}:
1-1im 2+1im
2-2im 3-1im
Base.stride
— Functionstride(A, k::Integer)
返回在维度 k
中相邻元素之间的内存距离(以元素数量为单位)。
另见: strides
。
示例
julia> A = fill(1, (3,4,5));
julia> stride(A,2)
3
julia> stride(A,3)
12
Base.strides
— FunctionBroadcast and vectorization
另请参见 dot syntax for vectorizing functions;例如,f.(args...)
隐式调用 broadcast(f, args...)
。与其依赖于 sin
等函数的“向量化”方法来处理数组,不如使用 sin.(a)
通过 broadcast
进行向量化。
Base.Broadcast.broadcast
— Functionbroadcast(f, As...)
对数组、元组、集合、Ref
和/或标量 As
进行函数 f
的广播。
广播将函数 f
应用到容器参数的元素和 As
中的标量本身。单例和缺失维度被扩展以匹配其他参数的范围,通过虚拟重复值来实现。默认情况下,仅考虑有限数量的类型作为标量,包括 Number
、String
、Symbol
、Type
、Function
以及一些常见的单例,如 missing
和 nothing
。所有其他参数按元素进行迭代或索引。
结果容器类型由以下规则确定:
- 如果所有参数都是标量或零维数组,则返回一个未包装的标量。
- 如果至少一个参数是元组,且所有其他参数都是标量或零维数组,则返回一个元组。
- 所有其他参数组合默认返回一个
Array
,但自定义容器类型可以定义自己的实现和类似提升的规则,以在作为参数出现时自定义结果。
广播有一种特殊语法:f.(args...)
等价于 broadcast(f, args...)
,嵌套的 f.(g.(args...))
调用被融合为一个单一的广播循环。
示例
julia> A = [1, 2, 3, 4, 5]
5-element Vector{Int64}:
1
2
3
4
5
julia> B = [1 2; 3 4; 5 6; 7 8; 9 10]
5×2 Matrix{Int64}:
1 2
3 4
5 6
7 8
9 10
julia> broadcast(+, A, B)
5×2 Matrix{Int64}:
2 3
5 6
8 9
11 12
14 15
julia> parse.(Int, ["1", "2"])
2-element Vector{Int64}:
1
2
julia> abs.((1, -2))
(1, 2)
julia> broadcast(+, 1.0, (0, -2.0))
(1.0, -1.0)
julia> (+).([[0,2], [1,3]], Ref{Vector{Int}}([1,-1]))
2-element Vector{Vector{Int64}}:
[1, 1]
[2, 2]
julia> string.(("one","two","three","four"), ": ", 1:4)
4-element Vector{String}:
"one: 1"
"two: 2"
"three: 3"
"four: 4"
Base.Broadcast.broadcast!
— Functionbroadcast!(f, dest, As...)
像 broadcast
一样,但将 broadcast(f, As...)
的结果存储在 dest
数组中。请注意,dest
仅用于存储结果,并不提供 f
的参数,除非它也在 As
中列出,例如 broadcast!(f, A, A, B)
来执行 A[:] = broadcast(f, A, B)
。
示例
julia> A = [1.0; 0.0]; B = [0.0; 0.0];
julia> broadcast!(+, B, A, (0, -2.0));
julia> B
2-element Vector{Float64}:
1.0
-2.0
julia> A
2-element Vector{Float64}:
1.0
0.0
julia> broadcast!(+, A, A, (0, -2.0));
julia> A
2-element Vector{Float64}:
1.0
-2.0
Base.Broadcast.@__dot__
— Macro@. expr
将 expr
中的每个函数调用或运算符转换为“点调用”(例如,将 f(x)
转换为 f.(x)
),并将 expr
中的每个赋值转换为“点赋值”(例如,将 +=
转换为 .+=
)。
如果您想要避免为 expr
中的某些函数调用添加点,请使用 $
将这些函数调用拼接在一起。例如,@. sqrt(abs($sort(x)))
等价于 sqrt.(abs.(sort(x)))
(sort
不加点)。
(@.
等价于对 @__dot__
的调用。)
示例
julia> x = 1.0:3.0; y = similar(x);
julia> @. y = x + 3 * sin(x)
3-element Vector{Float64}:
3.5244129544236893
4.727892280477045
3.4233600241796016
有关自定义类型的专门广播,请参见
Base.Broadcast.BroadcastStyle
— TypeBroadcastStyle
是一个抽象类型和特征函数,用于确定对象在广播下的行为。 BroadcastStyle(typeof(x))
返回与 x
相关联的样式。要自定义类型的广播行为,可以通过定义类型/方法对来声明样式
struct MyContainerStyle <: BroadcastStyle end
Base.BroadcastStyle(::Type{<:MyContainer}) = MyContainerStyle()
然后编写操作 Broadcasted{MyContainerStyle}
的方法(至少 similar
)。还有几个预定义的 BroadcastStyle
子类型,您可以利用它们;有关更多信息,请参见 Interfaces chapter。
Base.Broadcast.AbstractArrayStyle
— TypeBroadcast.AbstractArrayStyle{N} <: BroadcastStyle
是与 AbstractArray
类型相关的任何样式的抽象超类型。N
参数是维度,这对于仅支持特定维度的 AbstractArray 类型非常方便:
struct SparseMatrixStyle <: Broadcast.AbstractArrayStyle{2} end
Base.BroadcastStyle(::Type{<:SparseMatrixCSC}) = SparseMatrixStyle()
对于支持任意维度的 AbstractArray
类型,N
可以设置为 Any
:
struct MyArrayStyle <: Broadcast.AbstractArrayStyle{Any} end
Base.BroadcastStyle(::Type{<:MyArray}) = MyArrayStyle()
在您希望能够混合多个 AbstractArrayStyle
并跟踪维度的情况下,您的样式需要支持 Val
构造函数:
struct MyArrayStyleDim{N} <: Broadcast.AbstractArrayStyle{N} end
(::Type{<:MyArrayStyleDim})(::Val{N}) where N = MyArrayStyleDim{N}()
请注意,如果两个或多个 AbstractArrayStyle
子类型发生冲突,广播机制将回退到生成 Array
。如果这不可取,您可能需要定义二元 BroadcastStyle
规则来控制输出类型。
Base.Broadcast.ArrayStyle
— TypeBroadcast.ArrayStyle{MyArrayType}()
是一个 BroadcastStyle
,表示一个对象在广播时表现得像一个数组。它提供了一种简单的方法来为特定的 AbstractArray
容器类型构造 Broadcast.AbstractArrayStyle
。以这种方式创建的广播样式会失去维度信息;如果对你的类型保持维度信息很重要,你应该创建自己的自定义 Broadcast.AbstractArrayStyle
。
Base.Broadcast.DefaultArrayStyle
— TypeBroadcast.DefaultArrayStyle{N}()
是一个 BroadcastStyle
,表示一个对象在广播时表现为 N
维数组。具体来说,DefaultArrayStyle
用于任何未定义专门样式的 AbstractArray
类型,并且在没有其他 broadcast
参数的覆盖时,结果输出类型为 Array
。当有多个输入传递给 broadcast
时,DefaultArrayStyle
会“输给”任何其他 Broadcast.ArrayStyle
。
Base.Broadcast.broadcastable
— FunctionBroadcast.broadcastable(x)
返回 x
或一个类似 x
的对象,使其支持 axes
、索引,并且其类型支持 ndims
。
如果 x
支持迭代,则返回的值应具有与 collect(x)
相同的 axes
和索引行为。
如果 x
不是 AbstractArray
但支持 axes
、索引,并且其类型支持 ndims
,那么 broadcastable(::typeof(x))
可以实现为仅返回自身。此外,如果 x
定义了自己的 BroadcastStyle
,那么它必须定义其 broadcastable
方法以返回自身,以便自定义样式生效。
示例
julia> Broadcast.broadcastable([1,2,3]) # 像 `identity`,因为数组已经支持 axes 和索引
3-element Vector{Int64}:
1
2
3
julia> Broadcast.broadcastable(Int) # 类型不支持 axes、索引或迭代,但通常用作标量
Base.RefValue{Type{Int64}}(Int64)
julia> Broadcast.broadcastable("hello") # 字符串打破了匹配迭代的惯例,表现得像标量
Base.RefValue{String}("hello")
Base.Broadcast.combine_axes
— Functioncombine_axes(As...) -> Tuple
确定在 As
中所有值的广播结果轴。
julia> Broadcast.combine_axes([1], [1 2; 3 4; 5 6])
(Base.OneTo(3), Base.OneTo(2))
julia> Broadcast.combine_axes(1, 1, 1)
()
Base.Broadcast.combine_styles
— Functioncombine_styles(cs...) -> BroadcastStyle
决定对于任意数量的值参数使用哪种 BroadcastStyle
。使用 BroadcastStyle
获取每个参数的样式,并使用 result_style
组合样式。
示例
julia> Broadcast.combine_styles([1], [1 2; 3 4])
Base.Broadcast.DefaultArrayStyle{2}()
Base.Broadcast.result_style
— Functionresult_style(s1::BroadcastStyle[, s2::BroadcastStyle]) -> BroadcastStyle
接受一个或两个 BroadcastStyle
,并使用 BroadcastStyle
组合它们以确定一个共同的 BroadcastStyle
。
示例
julia> Broadcast.result_style(Broadcast.DefaultArrayStyle{0}(), Broadcast.DefaultArrayStyle{3}())
Base.Broadcast.DefaultArrayStyle{3}()
julia> Broadcast.result_style(Broadcast.Unknown(), Broadcast.DefaultArrayStyle{1}())
Base.Broadcast.DefaultArrayStyle{1}()
Indexing and assignment
Base.getindex
— Methodgetindex(A, inds...)
返回由索引 inds
选择的数组 A
的子集。
每个索引可以是任何 支持的索引类型,例如 Integer
、CartesianIndex
、范围 或 支持的索引数组。可以使用一个 : 来选择特定维度上的所有元素,布尔数组(例如 Array{Bool}
或 BitArray
)可以用来过滤对应索引为 true
的元素。
当 inds
选择多个元素时,此函数返回一个新分配的数组。要在不复制的情况下索引多个元素,请改用 view
。
有关详细信息,请参见手册中的 数组索引 部分。
示例
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> getindex(A, 1)
1
julia> getindex(A, [2, 1])
2-element Vector{Int64}:
3
1
julia> getindex(A, 2:4)
3-element Vector{Int64}:
3
2
4
julia> getindex(A, 2, 1)
3
julia> getindex(A, CartesianIndex(2, 1))
3
julia> getindex(A, :, 2)
2-element Vector{Int64}:
2
4
julia> getindex(A, 2, :)
2-element Vector{Int64}:
3
4
julia> getindex(A, A .> 2)
2-element Vector{Int64}:
3
4
Base.setindex!
— Methodsetindex!(A, X, inds...)
A[inds...] = X
将数组 X
中的值存储在 A
的某个子集内,具体由 inds
指定。语法 A[inds...] = X
等价于 (setindex!(A, X, inds...); X)
。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
示例
julia> A = zeros(2,2);
julia> setindex!(A, [10, 20], [1, 2]);
julia> A[[3, 4]] = [30, 40];
julia> A
2×2 Matrix{Float64}:
10.0 30.0
20.0 40.0
Base.nextind
— Functionnextind(A, i)
返回 A
中 i
之后的索引。返回的索引通常等于整数 i + 1
。此函数对于通用代码非常有用。
返回的索引可能超出边界。考虑使用 checkbounds
。
另见: prevind
。
示例
julia> x = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> nextind(x, 1) # 有效结果
2
julia> nextind(x, 4) # 无效结果
5
julia> nextind(x, CartesianIndex(1, 1)) # 有效结果
CartesianIndex(2, 1)
julia> nextind(x, CartesianIndex(2, 2)) # 无效结果
CartesianIndex(1, 3)
Base.prevind
— Functionprevind(A, i)
返回 A
中 i
之前的索引。返回的索引通常等于整数 i - 1
。此函数对于通用代码可能很有用。
返回的索引可能超出范围。考虑使用 checkbounds
。
另请参见:nextind
。
示例
julia> x = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> prevind(x, 4) # 有效结果
3
julia> prevind(x, 1) # 无效结果
0
julia> prevind(x, CartesianIndex(2, 2)) # 有效结果
CartesianIndex(1, 2)
julia> prevind(x, CartesianIndex(1, 1)) # 无效结果
CartesianIndex(2, 0)
Base.copyto!
— Methodcopyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest
将 src
中范围为 Rsrc
的块复制到 dest
中范围为 Rdest
的块。两个区域的大小必须匹配。
示例
julia> A = zeros(5, 5);
julia> B = [1 2; 3 4];
julia> Ainds = CartesianIndices((2:3, 2:3));
julia> Binds = CartesianIndices(B);
julia> copyto!(A, Ainds, B, Binds)
5×5 Matrix{Float64}:
0.0 0.0 0.0 0.0 0.0
0.0 1.0 2.0 0.0 0.0
0.0 3.0 4.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
Base.copy!
— Functioncopy!(dst, src) -> dst
就地 copy
将 src
复制到 dst
,丢弃 dst
中的任何现有元素。如果 dst
和 src
是相同类型,则在调用后应满足 dst == src
。如果 dst
和 src
是多维数组,则它们必须具有相等的 axes
。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
另请参见 copyto!
。
此方法至少需要 Julia 1.1。在 Julia 1.0 中,此方法可通过 Future
标准库作为 Future.copy!
使用。
Base.isassigned
— Functionisassigned(array, i) -> Bool
测试给定数组是否有与索引 i
关联的值。如果索引超出范围或具有未定义的引用,则返回 false
。
示例
julia> isassigned(rand(3, 3), 5)
true
julia> isassigned(rand(3, 3), 3 * 3 + 1)
false
julia> mutable struct Foo end
julia> v = similar(rand(3), Foo)
3-element Vector{Foo}:
#undef
#undef
#undef
julia> isassigned(v, 1)
false
Base.Colon
— TypeColon()
冒号 (:) 用于一次性索引整个对象或维度。
直接在 Colon 上定义的操作非常少;相反,它们通过 to_indices
转换为内部向量类型 (Base.Slice
),以表示它们所跨越的索引集合,然后再使用。
Colon
的单例实例也是一个用于构造范围的函数;请参见 :
。
Base.IteratorsMD.CartesianIndex
— TypeCartesianIndex(i, j, k...) -> I
CartesianIndex((i, j, k...)) -> I
创建一个多维索引 I
,可以用于索引多维数组 A
。特别地,A[I]
等价于 A[i,j,k...]
。可以自由混合整数和 CartesianIndex
索引;例如,A[Ipre, i, Ipost]
(其中 Ipre
和 Ipost
是 CartesianIndex
索引,i
是 Int
)在编写沿着任意维度的数组的算法时可以是一个有用的表达式。
CartesianIndex
有时由 eachindex
生成,并且在使用显式的 CartesianIndices
进行迭代时总是会生成。
I::CartesianIndex
被视为 broadcast
的“标量”(而不是容器)。为了迭代 CartesianIndex
的组件,可以使用 Tuple(I)
将其转换为元组。
示例
julia> A = reshape(Vector(1:16), (2, 2, 2, 2))
2×2×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
1 3
2 4
[:, :, 2, 1] =
5 7
6 8
[:, :, 1, 2] =
9 11
10 12
[:, :, 2, 2] =
13 15
14 16
julia> A[CartesianIndex((1, 1, 1, 1))]
1
julia> A[CartesianIndex((1, 1, 1, 2))]
9
julia> A[CartesianIndex((1, 1, 2, 1))]
5
将 CartesianIndex
作为 broadcast
的“标量”需要 Julia 1.10;在之前的版本中,请使用 Ref(I)
。
Base.IteratorsMD.CartesianIndices
— TypeCartesianIndices(sz::Dims) -> R
CartesianIndices((istart:[istep:]istop, jstart:[jstep:]jstop, ...)) -> R
定义一个区域 R
,跨越一个多维矩形范围的整数索引。这些索引最常见于迭代的上下文中,其中 for I in R ... end
将返回与嵌套循环等效的 CartesianIndex
索引 I
for j = jstart:jstep:jstop
for i = istart:istep:istop
...
end
end
因此,这些对于编写在任意维度中工作的算法非常有用。
CartesianIndices(A::AbstractArray) -> R
作为一种便利,从数组构造 CartesianIndices
会生成其索引的范围。
步长范围方法 CartesianIndices((istart:istep:istop, jstart:[jstep:]jstop, ...))
至少需要 Julia 1.6。
示例
julia> foreach(println, CartesianIndices((2, 2, 2)))
CartesianIndex(1, 1, 1)
CartesianIndex(2, 1, 1)
CartesianIndex(1, 2, 1)
CartesianIndex(2, 2, 1)
CartesianIndex(1, 1, 2)
CartesianIndex(2, 1, 2)
CartesianIndex(1, 2, 2)
CartesianIndex(2, 2, 2)
julia> CartesianIndices(fill(1, (2,3)))
CartesianIndices((2, 3))
线性索引与笛卡尔索引之间的转换
线性索引到笛卡尔索引的转换利用了 CartesianIndices
是一个 AbstractArray
并且可以线性索引的事实:
julia> cartesian = CartesianIndices((1:3, 1:2))
CartesianIndices((1:3, 1:2))
julia> cartesian[4]
CartesianIndex(1, 2)
julia> cartesian = CartesianIndices((1:2:5, 1:2))
CartesianIndices((1:2:5, 1:2))
julia> cartesian[2, 2]
CartesianIndex(3, 2)
广播
CartesianIndices
支持与 CartesianIndex
的广播算术 (+ 和 -)。
CartesianIndices
的广播至少需要 Julia 1.1。
julia> CIs = CartesianIndices((2:3, 5:6))
CartesianIndices((2:3, 5:6))
julia> CI = CartesianIndex(3, 4)
CartesianIndex(3, 4)
julia> CIs .+ CI
CartesianIndices((5:6, 9:10))
有关笛卡尔到线性索引转换,请参见 LinearIndices
。
Base.Dims
— TypeDims{N}
一个包含 N
个 Int
的 NTuple
,用于表示 AbstractArray
的维度。
Base.LinearIndices
— TypeLinearIndices(A::AbstractArray)
返回一个与 A
具有相同形状和 axes
的 LinearIndices
数组,保存 A
中每个条目的线性索引。使用笛卡尔索引对该数组进行索引可以将其映射到线性索引。
对于常规索引的数组(索引从 1 开始)或任何多维数组,线性索引的范围是从 1 到 length(A)
。然而,对于 AbstractVector
,线性索引是 axes(A, 1)
,因此对于具有非常规索引的向量,线性索引并不从 1 开始。
调用此函数是编写利用线性索引的算法的“安全”方式。
示例
julia> A = fill(1, (5,6,7));
julia> b = LinearIndices(A);
julia> extrema(b)
(1, 210)
LinearIndices(inds::CartesianIndices) -> R
LinearIndices(sz::Dims) -> R
LinearIndices((istart:istop, jstart:jstop, ...)) -> R
返回一个具有指定形状或 axes
的 LinearIndices
数组。
示例
此构造函数的主要目的是直观地将笛卡尔索引转换为线性索引:
julia> linear = LinearIndices((1:3, 1:2))
3×2 LinearIndices{2, Tuple{UnitRange{Int64}, UnitRange{Int64}}}:
1 4
2 5
3 6
julia> linear[1,2]
4
Base.to_indices
— Functionto_indices(A, I::Tuple)
将元组 I
转换为用于索引数组 A
的索引元组。
返回的元组必须仅包含 Int
或 AbstractArray
的标量索引,这些索引是数组 A
所支持的。遇到未知的索引类型时将会报错。
对于简单的索引类型,它会调用未导出的 Base.to_index(A, i)
来处理每个索引 i
。虽然这个内部函数并不打算直接调用,但 Base.to_index
可以通过自定义数组或索引类型进行扩展,以提供自定义的索引行为。
更复杂的索引类型可能需要更多关于它们索引的维度的上下文。为了支持这些情况,to_indices(A, I)
调用 to_indices(A, axes(A), I)
,然后递归地遍历给定的索引元组和 A
的维度索引。因此,并不是所有的索引类型都能保证传播到 Base.to_index
。
示例
julia> A = zeros(1,2,3,4);
julia> to_indices(A, (1,1,2,2))
(1, 1, 2, 2)
julia> to_indices(A, (1,1,2,20)) # 不进行边界检查
(1, 1, 2, 20)
julia> to_indices(A, (CartesianIndex((1,)), 2, CartesianIndex((3,4)))) # 异常索引
(1, 2, 3, 4)
julia> to_indices(A, ([1,1], 1:2, 3, 4))
([1, 1], 1:2, 3, 4)
julia> to_indices(A, (1,2)) # 不进行形状检查
(1, 2)
Base.checkbounds
— Functioncheckbounds(Bool, A, I...)
如果指定的索引 I
在给定数组 A
的范围内,则返回 true
。AbstractArray
的子类型应该专门化此方法,如果它们需要提供自定义的边界检查行为;然而,在许多情况下,可以依赖于 A
的索引和 checkindex
。
另请参见 checkindex
。
示例
julia> A = rand(3, 3);
julia> checkbounds(Bool, A, 2)
true
julia> checkbounds(Bool, A, 3, 4)
false
julia> checkbounds(Bool, A, 1:3)
true
julia> checkbounds(Bool, A, 1:3, 2:4)
false
checkbounds(A, I...)
如果指定的索引 I
不在给定数组 A
的范围内,则抛出错误。
Base.checkindex
— Functioncheckindex(Bool, inds::AbstractUnitRange, index)
如果给定的 index
在 inds
的范围内,则返回 true
。希望作为所有数组的索引行为的自定义类型可以扩展此方法,以提供专门的边界检查实现。
另见 checkbounds
。
示例
julia> checkindex(Bool, 1:20, 8)
true
julia> checkindex(Bool, 1:20, 21)
false
Base.elsize
— Functionelsize(type)
计算在给定 type
中存储的 eltype
的连续元素之间的内存步幅(以字节为单位),如果数组元素以均匀线性步幅密集存储。
示例
julia> Base.elsize(rand(Float32, 10))
4
Views (SubArrays and other view types)
“视图”是一种数据结构,类似于数组(它是 AbstractArray
的一个子类型),但其底层数据实际上是另一个数组的一部分。
例如,如果 x
是一个数组,且 v = @view x[1:10]
,那么 v
的行为就像一个包含 10 个元素的数组,但它的数据实际上是访问 x
的前 10 个元素。对视图进行写入,例如 v[3] = 2
,会直接写入底层数组 x
(在这种情况下修改 x[3]
)。
切片操作如 x[1:10]
默认会在 Julia 中创建一个副本。@view x[1:10]
将其更改为使用视图。@views
宏可以用于整个代码块(例如 @views function foo() .... end
或 @views begin ... end
),以将该块中的所有切片操作更改为使用视图。有时创建数据的副本更快,有时使用视图更快,正如在 performance tips 中所描述的。
Base.view
— Functionview(A, inds...)
像 getindex
一样,但返回一个轻量级数组,该数组懒惰地引用(或有效地是对)父数组 A
在给定索引或索引 inds
处的视图,而不是急切地提取元素或构造一个复制的子集。对返回值(通常是 SubArray
)调用 getindex
或 setindex!
会动态计算访问或修改父数组的索引。如果在调用 view
之后更改父数组的形状,则行为是未定义的,因为对父数组没有边界检查;例如,这可能会导致段错误。
一些不可变的父数组(如范围)可能会选择在某些情况下简单地重新计算一个新数组,而不是返回 SubArray
,如果这样做是高效的并且提供兼容的语义。
在 Julia 1.6 或更高版本中,可以在 AbstractString
上调用 view
,返回一个 SubString
。
示例
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> b = view(A, :, 1)
2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
1
3
julia> fill!(b, 0)
2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
0
0
julia> A # 注意 A 已经改变,即使我们修改了 b
2×2 Matrix{Int64}:
0 2
0 4
julia> view(2:5, 2:3) # 返回一个范围,因为类型是不可变的
3:4
Base.@view
— Macro@view A[inds...]
将索引表达式 A[inds...]
转换为等效的 view
调用。
这只能直接应用于单个索引表达式,并且对于包含特殊 begin
或 end
索引语法的表达式(如 A[begin, 2:end-1]
,因为这些在正常的 view
函数中不受支持)特别有帮助。
请注意,@view
不能用作常规赋值的目标(例如,@view(A[1, 2:end]) = ...
),未装饰的 索引赋值(A[1, 2:end] = ...
)或广播索引赋值(A[1, 2:end] .= ...
)也不会复制。然而,它对于 更新 广播赋值是有用的,例如 @view(A[1, 2:end]) .+= 1
,因为这是 @view(A[1, 2:end]) .= @view(A[1, 2:end]) + 1
的简单语法,而右侧的索引表达式在没有 @view
的情况下会复制。
另见 @views
以将整个代码块切换为使用视图进行非标量索引。
在索引表达式中使用 begin
来引用第一个索引需要至少 Julia 1.5。
示例
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> b = @view A[:, 1]
2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
1
3
julia> fill!(b, 0)
2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
0
0
julia> A
2×2 Matrix{Int64}:
0 2
0 4
Base.@views
— Macro@views 表达式
将给定表达式(可以是 begin
/end
块、循环、函数等)中的每个数组切片操作转换为返回视图。标量索引、非数组类型和显式 getindex
调用(与 array[...]
相对)不受影响。
同样,@views
将字符串切片转换为 SubString
视图。
!!! 注意 @views
宏仅影响在给定 expression
中显式出现的 array[...]
表达式,而不影响由该代码调用的函数中发生的数组切片。
!!! 兼容 "Julia 1.5" 在索引表达式中使用 begin
来引用第一个索引是在 Julia 1.4 中实现的,但仅在 Julia 1.5 开始支持 @views
。
示例
julia> A = zeros(3, 3);
julia> @views for row in 1:3
b = A[row, :] # b 是一个视图,而不是一个副本
b .= row # 将每个元素赋值为行索引
end
julia> A
3×3 Matrix{Float64}:
1.0 1.0 1.0
2.0 2.0 2.0
3.0 3.0 3.0
Base.parent
— Functionparent(A)
返回视图的基础父对象。类型为 SubArray
、SubString
、ReshapedArray
或 LinearAlgebra.Transpose
的对象的父对象是创建对象时传递给 view
、reshape
、transpose
等的参数。如果输入不是一个包装对象,则返回输入本身。如果输入被多次包装,则只会移除最外层的包装。
示例
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> V = view(A, 1:2, :)
2×2 view(::Matrix{Int64}, 1:2, :) with eltype Int64:
1 2
3 4
julia> parent(V)
2×2 Matrix{Int64}:
1 2
3 4
Base.parentindices
— Functionparentindices(A)
返回与视图 A
对应的 parent
中的索引。
示例
julia> A = [1 2; 3 4];
julia> V = view(A, 1, :)
2-element view(::Matrix{Int64}, 1, :) with eltype Int64:
1
2
julia> parentindices(V)
(1, Base.Slice(Base.OneTo(2)))
Base.selectdim
— Functionselectdim(A, d::Integer, i)
返回 A
的所有数据的视图,其中维度 d
的索引等于 i
。
等价于 view(A,:,:,...,i,:,:,...)
,其中 i
位于位置 d
。
另见: eachslice
。
示例
julia> A = [1 2 3 4; 5 6 7 8]
2×4 Matrix{Int64}:
1 2 3 4
5 6 7 8
julia> selectdim(A, 2, 3)
2-element view(::Matrix{Int64}, :, 3) with eltype Int64:
3
7
julia> selectdim(A, 2, 3:4)
2×2 view(::Matrix{Int64}, :, 3:4) with eltype Int64:
3 4
7 8
Base.reinterpret
— Functionreinterpret(::Type{Out}, x::In)
将二进制数据中 isbits 值 x
的类型解释更改为 isbits 类型 Out
。Out
的大小(忽略填充)必须与 x
的类型大小相同。例如,reinterpret(Float32, UInt32(7))
将与 UInt32(7)
对应的 4 个字节解释为 Float32
。注意 reinterpret(In, reinterpret(Out, x)) === x
julia> reinterpret(Float32, UInt32(7))
1.0f-44
julia> reinterpret(NTuple{2, UInt8}, 0x1234)
(0x34, 0x12)
julia> reinterpret(UInt16, (0x34, 0x12))
0x1234
julia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))
(0x0301, 0x02)
填充的处理与 reinterpret(::DataType, ::AbstractArray) 不同。
如果 Out
中某些位的组合被认为无效,并且类型的构造函数和方法会阻止这些组合,请谨慎使用。没有额外验证可能会导致意外行为。
reinterpret(T::DataType, A::AbstractArray)
构造一个数组的视图,该视图具有与给定数组相同的二进制数据,但元素类型为 T
。
此函数也适用于“惰性”数组,其元素在被显式检索之前不会被计算。例如,在范围 1:6
上使用 reinterpret
的效果与在稠密向量 collect(1:6)
上的效果类似:
julia> reinterpret(Float32, UInt32[1 2 3 4 5])
1×5 reinterpret(Float32, ::Matrix{UInt32}):
1.0f-45 3.0f-45 4.0f-45 6.0f-45 7.0f-45
julia> reinterpret(Complex{Int}, 1:6)
3-element reinterpret(Complex{Int64}, ::UnitRange{Int64}):
1 + 2im
3 + 4im
5 + 6im
如果填充位的位置在 T
和 eltype(A)
之间不对齐,则结果数组将是只读或只写的,以防止无效位被写入或读取。
julia> a = reinterpret(Tuple{UInt8, UInt32}, UInt32[1, 2])
1-element reinterpret(Tuple{UInt8, UInt32}, ::Vector{UInt32}):
(0x01, 0x00000002)
julia> a[1] = 3
ERROR: 类型 Tuple{UInt8, UInt32} 的填充与类型 UInt32 不兼容。
julia> b = reinterpret(UInt32, Tuple{UInt8, UInt32}[(0x01, 0x00000002)]); # 显示将出错
julia> b[1]
ERROR: 类型 UInt32 的填充与类型 Tuple{UInt8, UInt32} 不兼容。
reinterpret(reshape, T, A::AbstractArray{S}) -> B
改变 A
的类型解释,同时消耗或添加一个“通道维度”。
如果 sizeof(T) = n*sizeof(S)
且 n>1
,A
的第一维必须为大小 n
,而 B
缺少 A
的第一维。相反,如果 sizeof(S) = n*sizeof(T)
且 n>1
,B
将获得一个新的大小为 n
的第一维。如果 sizeof(T) == sizeof(S)
,则维度不变。
此方法至少需要 Julia 1.6。
示例
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> reinterpret(reshape, Complex{Int}, A) # 结果是一个向量
2-element reinterpret(reshape, Complex{Int64}, ::Matrix{Int64}) with eltype Complex{Int64}:
1 + 3im
2 + 4im
julia> a = [(1,2,3), (4,5,6)]
2-element Vector{Tuple{Int64, Int64, Int64}}:
(1, 2, 3)
(4, 5, 6)
julia> reinterpret(reshape, Int, a) # 结果是一个矩阵
3×2 reinterpret(reshape, Int64, ::Vector{Tuple{Int64, Int64, Int64}}) with eltype Int64:
1 4
2 5
3 6
Base.reshape
— Functionreshape(A, dims...) -> AbstractArray
reshape(A, dims) -> AbstractArray
返回一个与 A
具有相同数据的数组,但具有不同的维度大小或维度数量。这两个数组共享相同的底层数据,因此结果是可变的当且仅当 A
是可变的,并且设置一个的元素会改变另一个的值。
新维度可以作为参数列表或形状元组指定。最多可以用 :
指定一个维度,在这种情况下,其长度会被计算为与所有指定维度的乘积等于原始数组 A
的长度。元素的总数必须保持不变。
示例
julia> A = Vector(1:16)
16-element Vector{Int64}:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
julia> reshape(A, (4, 4))
4×4 Matrix{Int64}:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> reshape(A, 2, :)
2×8 Matrix{Int64}:
1 3 5 7 9 11 13 15
2 4 6 8 10 12 14 16
julia> reshape(1:6, 2, 3)
2×3 reshape(::UnitRange{Int64}, 2, 3) with eltype Int64:
1 3 5
2 4 6
Base.dropdims
— Functiondropdims(A; dims)
返回一个与 A
具有相同数据的数组,但移除了由 dims
指定的维度。size(A,d)
必须对 dims
中的每个 d
等于 1,且禁止重复的维度或超出 1:ndims(A)
的数字。
结果与 A
共享相同的底层数据,因此结果是可变的当且仅当 A
是可变的,并且一个的元素设置会改变另一个的值。
示例
julia> a = reshape(Vector(1:4),(2,2,1,1))
2×2×1×1 Array{Int64, 4}:
[:, :, 1, 1] =
1 3
2 4
julia> b = dropdims(a; dims=3)
2×2×1 Array{Int64, 3}:
[:, :, 1] =
1 3
2 4
julia> b[1,1,1] = 5; a
2×2×1×1 Array{Int64, 4}:
[:, :, 1, 1] =
5 3
2 4
Base.vec
— Functionvec(a::AbstractArray) -> AbstractVector
将数组 a
重新形状为一维列向量。如果 a
已经是 AbstractVector
,则返回 a
。结果数组与 a
共享相同的底层数据,因此只有在 a
是可变的情况下才会是可变的,在这种情况下,修改一个也会修改另一个。
示例
julia> a = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> vec(a)
6-element Vector{Int64}:
1
4
2
5
3
6
julia> vec(1:3)
1:3
Base.SubArray
— TypeSubArray{T,N,P,I,L} <: AbstractArray{T,N}
N
维视图,指向父数组(类型为 P
),元素类型为 T
,由索引元组(类型为 I
)限制。L
对于支持快速线性索引的类型为真,反之为假。
使用 view
函数构造 SubArray
。
Concatenation and permutation
Base.cat
— Functioncat(A...; dims)
沿着 dims
指定的维度连接输入数组。
在维度 d in dims
上,输出数组的大小为 sum(size(a,d) for a in A)
。在其他维度上,所有输入数组的大小应相同,这也将是输出数组在这些维度上的大小。
如果 dims
是一个单一数字,则不同的数组在该维度上紧密打包。如果 dims
是一个包含多个维度的可迭代对象,则沿着这些维度的位置会同时增加,每个输入数组填充其他地方为零。这允许构造块对角矩阵,如 cat(matrices...; dims=(1,2))
,以及它们的高维类比。
特殊情况 dims=1
是 vcat
,dims=2
是 hcat
。另见 hvcat
,hvncat
,stack
,repeat
。
关键字还接受 Val(dims)
。
对于多个维度,dims = Val(::Tuple)
是在 Julia 1.8 中添加的。
示例
在不同维度中连接两个数组:
julia> a = [1 2 3]
1×3 Matrix{Int64}:
1 2 3
julia> b = [4 5 6]
1×3 Matrix{Int64}:
4 5 6
julia> cat(a, b; dims=1)
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> cat(a, b; dims=2)
1×6 Matrix{Int64}:
1 2 3 4 5 6
julia> cat(a, b; dims=(1, 2))
2×6 Matrix{Int64}:
1 2 3 0 0 0
0 0 0 4 5 6
扩展帮助
连接 3D 数组:
julia> a = ones(2, 2, 3);
julia> b = ones(2, 2, 4);
julia> c = cat(a, b; dims=3);
julia> size(c) == (2, 2, 7)
true
连接不同大小的数组:
julia> cat([1 2; 3 4], [pi, pi], fill(10, 2,3,1); dims=2) # 同 hcat
2×6×1 Array{Float64, 3}:
[:, :, 1] =
1.0 2.0 3.14159 10.0 10.0 10.0
3.0 4.0 3.14159 10.0 10.0 10.0
构造一个块对角矩阵:
julia> cat(true, trues(2,2), trues(4)', dims=(1,2)) # 块对角
4×7 Matrix{Bool}:
1 0 0 0 0 0 0
0 1 1 0 0 0 0
0 1 1 0 0 0 0
0 0 0 1 1 1 1
julia> cat(1, [2], [3;;]; dims=Val(2))
1×3 Matrix{Int64}:
1 2 3
cat
不会连接两个字符串,你可能想使用 *
。
julia> a = "aaa";
julia> b = "bbb";
julia> cat(a, b; dims=1)
2-element Vector{String}:
"aaa"
"bbb"
julia> cat(a, b; dims=2)
1×2 Matrix{String}:
"aaa" "bbb"
julia> a * b
"aaabbb"
Base.vcat
— Functionvcat(A...)
垂直连接数组或数字。等价于 cat
(A...; dims=1)
,以及语法 [a; b; c]
。
要连接一个大型数组向量,reduce(vcat, A)
在 A isa AbstractVector{<:AbstractVecOrMat}
时调用高效方法,而不是逐对处理。
另请参见 hcat
,Iterators.flatten
,stack
。
示例
julia> v = vcat([1,2], [3,4])
4-element Vector{Int64}:
1
2
3
4
julia> v == vcat(1, 2, [3,4]) # 接受数字
true
julia> v == [1; 2; [3,4]] # 相同操作的语法
true
julia> summary(ComplexF64[1; 2; [3,4]]) # 提供元素类型的语法
"4-element Vector{ComplexF64}"
julia> vcat(range(1, 2, length=3)) # 收集惰性范围
3-element Vector{Float64}:
1.0
1.5
2.0
julia> two = ([10, 20, 30]', Float64[4 5 6; 7 8 9]) # 行向量和矩阵
([10 20 30], [4.0 5.0 6.0; 7.0 8.0 9.0])
julia> vcat(two...)
3×3 Matrix{Float64}:
10.0 20.0 30.0
4.0 5.0 6.0
7.0 8.0 9.0
julia> vs = [[1, 2], [3, 4], [5, 6]];
julia> reduce(vcat, vs) # 比 vcat(vs...) 更高效
6-element Vector{Int64}:
1
2
3
4
5
6
julia> ans == collect(Iterators.flatten(vs))
true
Base.hcat
— Functionhcat(A...)
水平连接数组或数字。等价于 cat
(A...; dims=2)
,以及语法 [a b c]
或 [a;; b;; c]
。
对于一个大型数组向量,reduce(hcat, A)
在 A isa AbstractVector{<:AbstractVecOrMat}
时调用高效的方法。对于一个向量的向量,这也可以写作 stack
(A)
。
示例
julia> hcat([1,2], [3,4], [5,6])
2×3 Matrix{Int64}:
1 3 5
2 4 6
julia> hcat(1, 2, [30 40], [5, 6, 7]') # 接受数字
1×7 Matrix{Int64}:
1 2 30 40 5 6 7
julia> ans == [1 2 [30 40] [5, 6, 7]'] # 相同操作的语法
true
julia> Float32[1 2 [30 40] [5, 6, 7]'] # 提供 eltype 的语法
1×7 Matrix{Float32}:
1.0 2.0 30.0 40.0 5.0 6.0 7.0
julia> ms = [zeros(2,2), [1 2; 3 4], [50 60; 70 80]];
julia> reduce(hcat, ms) # 比 hcat(ms...) 更高效
2×6 Matrix{Float64}:
0.0 0.0 1.0 2.0 50.0 60.0
0.0 0.0 3.0 4.0 70.0 80.0
julia> stack(ms) |> summary # 对矩阵的向量不一致
"2×2×3 Array{Float64, 3}"
julia> hcat(Int[], Int[], Int[]) # 空向量,每个大小为 (0,)
0×3 Matrix{Int64}
julia> hcat([1.1, 9.9], Matrix(undef, 2, 0)) # hcat 与空的 2×0 矩阵
2×1 Matrix{Any}:
1.1
9.9
Base.hvcat
— Functionhvcat(blocks_per_row::Union{Tuple{Vararg{Int}}, Int}, values...)
在一次调用中进行水平和垂直连接。此函数用于块矩阵语法。第一个参数指定每个块行中要连接的参数数量。如果第一个参数是一个单一整数 n
,则假定所有块行都有 n
个块列。
示例
julia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
(1, 2, 3, 4, 5, 6)
julia> [a b c; d e f]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> hvcat((3,3), a,b,c,d,e,f)
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> [a b; c d; e f]
3×2 Matrix{Int64}:
1 2
3 4
5 6
julia> hvcat((2,2,2), a,b,c,d,e,f)
3×2 Matrix{Int64}:
1 2
3 4
5 6
julia> hvcat((2,2,2), a,b,c,d,e,f) == hvcat(2, a,b,c,d,e,f)
true
Base.hvncat
— Functionhvncat(dim::Int, row_first, values...)
hvncat(dims::Tuple{Vararg{Int}}, row_first, values...)
hvncat(shape::Tuple{Vararg{Tuple}}, row_first, values...)
在一次调用中对多个 values
进行水平、垂直和 n 维连接。
此函数用于块矩阵语法。第一个参数指定连接的形状,类似于 hvcat
,作为元组的元组,或者指定沿每个轴的元素数量的维度,并用于确定输出维度。dims
形式性能更佳,当连接操作沿每个轴的元素数量相同时(例如,[a b; c d;;; e f ; g h])默认使用此形式。shape
形式用于沿每个轴的元素数量不平衡时(例如,[a b ; c])。不平衡语法需要额外的验证开销。dim
形式是仅沿一个维度连接的优化。row_first
指示 values
的排序方式。shape
的第一个和第二个元素的含义也根据 row_first
进行了交换。
示例
julia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
(1, 2, 3, 4, 5, 6)
julia> [a b c;;; d e f]
1×3×2 Array{Int64, 3}:
[:, :, 1] =
1 2 3
[:, :, 2] =
4 5 6
julia> hvncat((2,1,3), false, a,b,c,d,e,f)
2×1×3 Array{Int64, 3}:
[:, :, 1] =
1
2
[:, :, 2] =
3
4
[:, :, 3] =
5
6
julia> [a b;;; c d;;; e f]
1×2×3 Array{Int64, 3}:
[:, :, 1] =
1 2
[:, :, 2] =
3 4
[:, :, 3] =
5 6
julia> hvncat(((3, 3), (3, 3), (6,)), true, a, b, c, d, e, f)
1×3×2 Array{Int64, 3}:
[:, :, 1] =
1 2 3
[:, :, 2] =
4 5 6
构造参数的示例
[a b c ; d e f ;;;
g h i ; j k l ;;;
m n o ; p q r ;;;
s t u ; v w x]
⇒ dims = (2, 3, 4)
[a b ; c ;;; d ;;;;]
___ _ _
2 1 1 = 每行的元素数量 (2, 1, 1)
_______ _
3 1 = 每列的元素数量 (3, 1)
_____________
4 = 每个 3d 切片的元素数量 (4,)
_____________
4 = 每个 4d 切片的元素数量 (4,)
⇒ shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `row_first` = true
Base.stack
— Functionstack(iter; [dims])
将大小相等的数组(或其他可迭代对象)集合组合成一个更大的数组,通过沿一个或多个新维度排列它们。
默认情况下,元素的轴首先被放置,给出 size(result) = (size(first(iter))..., size(iter)...)
。这与 Iterators.flatten
(iter)
的元素顺序相同。
使用关键字 dims::Integer
,则 iter
的第 i
个元素变为切片 selectdim
(result, dims, i)
,使得 size(result, dims) == length(iter)
。在这种情况下,stack
反转了 eachslice
的作用,使用相同的 dims
。
各种 cat
函数也组合数组。然而,这些函数扩展了数组现有的(可能是微不足道的)维度,而不是将数组放置在新维度上。它们还接受作为单独参数的数组,而不是单个集合。
此函数至少需要 Julia 1.9。
示例
julia> vecs = (1:2, [30, 40], Float32[500, 600]);
julia> mat = stack(vecs)
2×3 Matrix{Float32}:
1.0 30.0 500.0
2.0 40.0 600.0
julia> mat == hcat(vecs...) == reduce(hcat, collect(vecs))
true
julia> vec(mat) == vcat(vecs...) == reduce(vcat, collect(vecs))
true
julia> stack(zip(1:4, 10:99)) # 接受任何迭代器的迭代器
2×4 Matrix{Int64}:
1 2 3 4
10 11 12 13
julia> vec(ans) == collect(Iterators.flatten(zip(1:4, 10:99)))
true
julia> stack(vecs; dims=1) # 与任何 cat 函数不同,vecs[1] 的第 1 轴是结果的第 2 轴
3×2 Matrix{Float32}:
1.0 2.0
30.0 40.0
500.0 600.0
julia> x = rand(3,4);
julia> x == stack(eachcol(x)) == stack(eachrow(x), dims=1) # eachslice 的逆
true
更高维度的示例:
julia> A = rand(5, 7, 11);
julia> E = eachslice(A, dims=2); # 一个矩阵的向量
julia> (element = size(first(E)), container = size(E))
(element = (5, 11), container = (7,))
julia> stack(E) |> size
(5, 11, 7)
julia> stack(E) == stack(E; dims=3) == cat(E...; dims=3)
true
julia> A == stack(E; dims=2)
true
julia> M = (fill(10i+j, 2, 3) for i in 1:5, j in 1:7);
julia> (element = size(first(M)), container = size(M))
(element = (2, 3), container = (5, 7))
julia> stack(M) |> size # 保持所有维度
(2, 3, 5, 7)
julia> stack(M; dims=1) |> size # vec(container) 沿 dims=1
(35, 2, 3)
julia> hvcat(5, M...) |> size # hvcat 将矩阵放在一起
(14, 15)
stack(f, args...; [dims])
对集合的每个元素应用一个函数,并将结果进行 stack
。或者对几个集合进行 zip
操作。
该函数应返回大小相同的数组(或元组,或其他迭代器)。这些将成为结果的切片,每个切片沿着 dims
(如果给定)或默认沿着最后的维度分隔。
示例
julia> stack(c -> (c, c-32), "julia")
2×5 Matrix{Char}:
'j' 'u' 'l' 'i' 'a'
'J' 'U' 'L' 'I' 'A'
julia> stack(eachrow([1 2 3; 4 5 6]), (10, 100); dims=1) do row, n
vcat(row, row .* n, row ./ n)
end
2×9 Matrix{Float64}:
1.0 2.0 3.0 10.0 20.0 30.0 0.1 0.2 0.3
4.0 5.0 6.0 400.0 500.0 600.0 0.04 0.05 0.06
Base.vect
— Functionvect(X...)
创建一个 Vector
,其元素类型由参数的 promote_typeof
计算得出,包含参数列表。
示例
julia> a = Base.vect(UInt8(1), 2.5, 1//2)
3-element Vector{Float64}:
1.0
2.5
0.5
Base.circshift
— Functioncircshift(A, shifts)
循环移位,即旋转,数组中的数据。第二个参数是一个元组或向量,给出在每个维度上移位的量,或者是一个整数,仅在第一个维度上移位。
另见: circshift!
, circcopy!
, bitrotate
, <<
.
示例
julia> b = reshape(Vector(1:16), (4,4))
4×4 Matrix{Int64}:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> circshift(b, (0,2))
4×4 Matrix{Int64}:
9 13 1 5
10 14 2 6
11 15 3 7
12 16 4 8
julia> circshift(b, (-1,0))
4×4 Matrix{Int64}:
2 6 10 14
3 7 11 15
4 8 12 16
1 5 9 13
julia> a = BitArray([true, true, false, false, true])
5-element BitVector:
1
1
0
0
1
julia> circshift(a, 1)
5-element BitVector:
1
1
1
0
0
julia> circshift(a, -1)
5-element BitVector:
1
0
0
1
1
Base.circshift!
— Functioncircshift!(dest, src, shifts)
循环移动,即旋转,src
中的数据,将结果存储在 dest
中。shifts
指定每个维度的移动量。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
另见 circshift
.
Base.circcopy!
— Functioncirccopy!(dest, src)
将 src
复制到 dest
,对每个维度的索引进行模其长度的操作。src
和 dest
必须具有相同的大小,但可以在其索引中有偏移;任何偏移都会导致(循环)包裹。如果数组具有重叠的索引,则在重叠的域上,dest
与 src
一致。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
另请参见: circshift
.
示例
julia> src = reshape(Vector(1:16), (4,4))
4×4 Array{Int64,2}:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> dest = OffsetArray{Int}(undef, (0:3,2:5))
julia> circcopy!(dest, src)
OffsetArrays.OffsetArray{Int64,2,Array{Int64,2}} with indices 0:3×2:5:
8 12 16 4
5 9 13 1
6 10 14 2
7 11 15 3
julia> dest[1:3,2:4] == src[1:3,2:4]
true
Base.findall
— Methodfindall(A)
返回一个向量 I
,其中包含 A
的 true
索引或键。如果 A
中没有这样的元素,则返回一个空数组。要搜索其他类型的值,请将谓词作为第一个参数传递。
索引或键与 keys(A)
和 pairs(A)
返回的类型相同。
另请参见:findfirst
,searchsorted
。
示例
julia> A = [true, false, false, true]
4-element Vector{Bool}:
1
0
0
1
julia> findall(A)
2-element Vector{Int64}:
1
4
julia> A = [true false; false true]
2×2 Matrix{Bool}:
1 0
0 1
julia> findall(A)
2-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(2, 2)
julia> findall(falses(3))
Int64[]
Base.findall
— Methodfindall(f::Function, A)
返回一个向量 I
,其中包含 A
的索引或键,满足 f(A[I])
返回 true
。如果 A
中没有这样的元素,则返回一个空数组。
索引或键与 keys(A)
和 pairs(A)
返回的类型相同。
示例
julia> x = [1, 3, 4]
3-element Vector{Int64}:
1
3
4
julia> findall(isodd, x)
2-element Vector{Int64}:
1
2
julia> A = [1 2 0; 3 4 0]
2×3 Matrix{Int64}:
1 2 0
3 4 0
julia> findall(isodd, A)
2-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(2, 1)
julia> findall(!iszero, A)
4-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(2, 1)
CartesianIndex(1, 2)
CartesianIndex(2, 2)
julia> d = Dict(:A => 10, :B => -1, :C => 0)
Dict{Symbol, Int64} with 3 entries:
:A => 10
:B => -1
:C => 0
julia> findall(x -> x >= 0, d)
2-element Vector{Symbol}:
:A
:C
Base.findfirst
— Methodfindfirst(A)
返回 A
中第一个 true
值的索引或键。如果未找到此类值,则返回 nothing
。要搜索其他类型的值,请将谓词作为第一个参数传递。
索引或键与 keys(A)
和 pairs(A)
返回的类型相同。
另请参见:findall
, findnext
, findlast
, searchsortedfirst
。
示例
julia> A = [false, false, true, false]
4-element Vector{Bool}:
0
0
1
0
julia> findfirst(A)
3
julia> findfirst(falses(3)) # 返回 nothing,但在 REPL 中未打印
julia> A = [false false; true false]
2×2 Matrix{Bool}:
0 0
1 0
julia> findfirst(A)
CartesianIndex(2, 1)
Base.findfirst
— Methodfindfirst(predicate::Function, A)
返回 A
中第一个使 predicate
返回 true
的元素的索引或键。如果没有这样的元素,则返回 nothing
。
索引或键与 keys(A)
和 pairs(A)
返回的类型相同。
示例
julia> A = [1, 4, 2, 2]
4-element Vector{Int64}:
1
4
2
2
julia> findfirst(iseven, A)
2
julia> findfirst(x -> x>10, A) # 返回 nothing,但在 REPL 中不打印
julia> findfirst(isequal(4), A)
2
julia> A = [1 4; 2 2]
2×2 Matrix{Int64}:
1 4
2 2
julia> findfirst(iseven, A)
CartesianIndex(2, 1)
Base.findlast
— Methodfindlast(A)
返回 A
中最后一个 true
值的索引或键。如果 A
中没有 true
值,则返回 nothing
。
索引或键与 keys(A)
和 pairs(A)
返回的类型相同。
另请参见:findfirst
,findprev
,findall
。
示例
julia> A = [true, false, true, false]
4-element Vector{Bool}:
1
0
1
0
julia> findlast(A)
3
julia> A = falses(2,2);
julia> findlast(A) # 返回 nothing,但在 REPL 中未打印
julia> A = [true false; true false]
2×2 Matrix{Bool}:
1 0
1 0
julia> findlast(A)
CartesianIndex(2, 1)
Base.findlast
— Methodfindlast(predicate::Function, A)
返回 A
中最后一个使 predicate
返回 true
的元素的索引或键。如果没有这样的元素,则返回 nothing
。
索引或键与 keys(A)
和 pairs(A)
返回的类型相同。
示例
julia> A = [1, 2, 3, 4]
4-element Vector{Int64}:
1
2
3
4
julia> findlast(isodd, A)
3
julia> findlast(x -> x > 5, A) # 返回 nothing,但在 REPL 中不打印
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> findlast(isodd, A)
CartesianIndex(2, 1)
Base.findnext
— Methodfindnext(A, i)
查找 A
中 i
之后或包括 i
的下一个 true
元素的索引,如果未找到则返回 nothing
。
索引与 keys(A)
和 pairs(A)
返回的类型相同。
示例
julia> A = [false, false, true, false]
4-element Vector{Bool}:
0
0
1
0
julia> findnext(A, 1)
3
julia> findnext(A, 4) # 返回 nothing,但在 REPL 中不打印
julia> A = [false false; true false]
2×2 Matrix{Bool}:
0 0
1 0
julia> findnext(A, CartesianIndex(1, 1))
CartesianIndex(2, 1)
Base.findnext
— Methodfindnext(predicate::Function, A, i)
查找在 i
之后或包括 i
的 A
中的元素的下一个索引,该元素使得 predicate
返回 true
,如果未找到则返回 nothing
。这适用于数组、字符串以及大多数支持 getindex
、keys(A)
和 nextind
的其他集合。
索引与 keys(A)
和 pairs(A)
返回的类型相同。
示例
julia> A = [1, 4, 2, 2];
julia> findnext(isodd, A, 1)
1
julia> findnext(isodd, A, 2) # 返回 nothing,但在 REPL 中未打印
julia> A = [1 4; 2 2];
julia> findnext(isodd, A, CartesianIndex(1, 1))
CartesianIndex(1, 1)
julia> findnext(isspace, "a b c", 3)
4
Base.findprev
— Methodfindprev(A, i)
查找在 i
之前或包括 i
的 A
中 true
元素的前一个索引,如果未找到则返回 nothing
。
索引与 keys(A)
和 pairs(A)
返回的类型相同。
另请参见: findnext
, findfirst
, findall
。
示例
julia> A = [false, false, true, true]
4-element Vector{Bool}:
0
0
1
1
julia> findprev(A, 3)
3
julia> findprev(A, 1) # 返回 nothing,但在 REPL 中未打印
julia> A = [false false; true true]
2×2 Matrix{Bool}:
0 0
1 1
julia> findprev(A, CartesianIndex(2, 1))
CartesianIndex(2, 1)
Base.findprev
— Methodfindprev(predicate::Function, A, i)
查找在 i
之前或包括 i
的 A
中的元素的前一个索引,该元素使得 predicate
返回 true
,如果未找到则返回 nothing
。这适用于数组、字符串以及大多数支持 getindex
、keys(A)
和 nextind
的其他集合。
索引与 keys(A)
和 pairs(A)
返回的类型相同。
示例
julia> A = [4, 6, 1, 2]
4-element Vector{Int64}:
4
6
1
2
julia> findprev(isodd, A, 1) # 返回 nothing,但在 REPL 中未打印
julia> findprev(isodd, A, 3)
3
julia> A = [4 6; 1 2]
2×2 Matrix{Int64}:
4 6
1 2
julia> findprev(isodd, A, CartesianIndex(1, 2))
CartesianIndex(2, 1)
julia> findprev(isspace, "a b c", 3)
2
Base.permutedims
— Functionpermutedims(A::AbstractArray, perm)
permutedims(A::AbstractMatrix)
对数组 A
的维度(轴)进行排列。perm
是一个元组或向量,包含 ndims(A)
个整数,指定排列顺序。
如果 A
是一个二维数组(AbstractMatrix
),则 perm
默认为 (2,1)
,交换 A
的两个轴(矩阵的行和列)。这与 transpose
不同,因为该操作不是递归的,这对于非数值值的数组(递归的 transpose
会抛出错误)和/或不表示线性算子的二维数组尤其有用。
对于一维数组,请参见 permutedims(v::AbstractVector)
,它返回一个1行的“矩阵”。
另请参见 permutedims!
,PermutedDimsArray
,transpose
,invperm
。
示例
二维数组:
与 transpose
不同,permutedims
可以用于交换任意非数值元素的二维数组的行和列,例如字符串:
julia> A = ["a" "b" "c"
"d" "e" "f"]
2×3 Matrix{String}:
"a" "b" "c"
"d" "e" "f"
julia> permutedims(A)
3×2 Matrix{String}:
"a" "d"
"b" "e"
"c" "f"
而且 permutedims
对于其元素本身是数值矩阵的矩阵产生的结果与 transpose
不同:
julia> a = [1 2; 3 4];
julia> b = [5 6; 7 8];
julia> c = [9 10; 11 12];
julia> d = [13 14; 15 16];
julia> X = [[a] [b]; [c] [d]]
2×2 Matrix{Matrix{Int64}}:
[1 2; 3 4] [5 6; 7 8]
[9 10; 11 12] [13 14; 15 16]
julia> permutedims(X)
2×2 Matrix{Matrix{Int64}}:
[1 2; 3 4] [9 10; 11 12]
[5 6; 7 8] [13 14; 15 16]
julia> transpose(X)
2×2 transpose(::Matrix{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:
[1 3; 2 4] [9 11; 10 12]
[5 7; 6 8] [13 15; 14 16]
多维数组
julia> A = reshape(Vector(1:8), (2,2,2))
2×2×2 Array{Int64, 3}:
[:, :, 1] =
1 3
2 4
[:, :, 2] =
5 7
6 8
julia> perm = (3, 1, 2); # 将最后一个维度放在最前面
julia> B = permutedims(A, perm)
2×2×2 Array{Int64, 3}:
[:, :, 1] =
1 2
5 6
[:, :, 2] =
3 4
7 8
julia> A == permutedims(B, invperm(perm)) # 逆排列
true
对于 B = permutedims(A, perm)
的每个维度 i
,其对应的 A
的维度将是 perm[i]
。这意味着等式 size(B, i) == size(A, perm[i])
成立。
julia> A = randn(5, 7, 11, 13);
julia> perm = [4, 1, 3, 2];
julia> B = permutedims(A, perm);
julia> size(B)
(13, 5, 11, 7)
julia> size(A)[perm] == ans
true
permutedims(v::AbstractVector)
将向量 v
重塑为 1 × length(v)
行矩阵。与 transpose
的不同之处在于该操作不是递归的,这对于非数值值的数组尤其有用(递归的 transpose
可能会抛出错误)。
示例
与 transpose
不同,permutedims
可以用于任意非数值元素的向量,例如字符串:
julia> permutedims(["a", "b", "c"])
1×3 Matrix{String}:
"a" "b" "c"
对于数字向量,permutedims(v)
的工作方式与 transpose(v)
非常相似,除了返回类型不同(它使用 reshape
而不是 LinearAlgebra.Transpose
视图,尽管两者与原始数组 v
共享内存):
julia> v = [1, 2, 3, 4]
4-element Vector{Int64}:
1
2
3
4
julia> p = permutedims(v)
1×4 Matrix{Int64}:
1 2 3 4
julia> r = transpose(v)
1×4 transpose(::Vector{Int64}) with eltype Int64:
1 2 3 4
julia> p == r
true
julia> typeof(r)
Transpose{Int64, Vector{Int64}}
julia> p[1] = 5; r[2] = 6; # 修改 p 或 r 也会改变 v
julia> v # 与 p 和 r 共享内存
4-element Vector{Int64}:
5
6
3
4
然而,对于其元素本身是数值矩阵的向量,permutedims
产生的结果与 transpose
不同:
julia> V = [[[1 2; 3 4]]; [[5 6; 7 8]]]
2-element Vector{Matrix{Int64}}:
[1 2; 3 4]
[5 6; 7 8]
julia> permutedims(V)
1×2 Matrix{Matrix{Int64}}:
[1 2; 3 4] [5 6; 7 8]
julia> transpose(V)
1×2 transpose(::Vector{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:
[1 3; 2 4] [5 7; 6 8]
Base.permutedims!
— Functionpermutedims!(dest, src, perm)
对数组 src
的维度进行排列,并将结果存储在数组 dest
中。perm
是一个指定长度为 ndims(src)
的排列向量。预分配的数组 dest
应该满足 size(dest) == size(src)[perm]
,并且会被完全覆盖。不支持就地排列,如果 src
和 dest
有重叠的内存区域,将会出现意外结果。
另见 permutedims
.
Base.PermutedDimsArrays.PermutedDimsArray
— TypePermutedDimsArray(A, perm) -> B
给定一个 AbstractArray A
,创建一个视图 B
,使得维度看起来被置换。类似于 permutedims
,但不进行复制(B
与 A
共享存储)。
另请参见 permutedims
,invperm
。
示例
julia> A = rand(3,5,4);
julia> B = PermutedDimsArray(A, (3,1,2));
julia> size(B)
(4, 3, 5)
julia> B[3,1,2] == A[1,2,3]
true
Base.promote_shape
— Functionpromote_shape(s1, s2)
检查两个数组形状的兼容性,允许尾随的单例维度,并返回维度更多的形状。
示例
julia> a = fill(1, (3,4,1,1,1));
julia> b = fill(1, (3,4));
julia> promote_shape(a,b)
(Base.OneTo(3), Base.OneTo(4), Base.OneTo(1), Base.OneTo(1), Base.OneTo(1))
julia> promote_shape((2,3,1,4), (2, 3, 1, 4, 1))
(2, 3, 1, 4, 1)
Array functions
Base.accumulate
— Functionaccumulate(op, A; dims::Integer, [init])
沿着 A
的维度 dims
进行累积操作 op
(对于向量,提供 dims
是可选的)。可以通过关键字参数可选地提供初始值 init
。另请参见 accumulate!
,以使用预分配的输出数组,这样可以提高性能并控制输出的精度(例如,避免溢出)。
对于常见操作,有 accumulate
的专用变体,见 cumsum
,cumprod
。有关懒惰版本,请参见 Iterators.accumulate
。
在非数组迭代器上使用 accumulate
至少需要 Julia 1.5。
示例
julia> accumulate(+, [1,2,3])
3-element Vector{Int64}:
1
3
6
julia> accumulate(min, (1, -2, 3, -4, 5), init=0)
(0, -2, -2, -4, -4)
julia> accumulate(/, (2, 4, Inf), init=100)
(50.0, 12.5, 0.0)
julia> accumulate(=>, i^2 for i in 1:3)
3-element Vector{Any}:
1
1 => 4
(1 => 4) => 9
julia> accumulate(+, fill(1, 3, 4))
3×4 Matrix{Int64}:
1 4 7 10
2 5 8 11
3 6 9 12
julia> accumulate(+, fill(1, 2, 5), dims=2, init=100.0)
2×5 Matrix{Float64}:
101.0 102.0 103.0 104.0 105.0
101.0 102.0 103.0 104.0 105.0
Base.accumulate!
— Functionaccumulate!(op, B, A; [dims], [init])
对 A
进行累积操作 op
,沿着维度 dims
,将结果存储在 B
中。对于向量,提供 dims
是可选的。如果给定了关键字参数 init
,则其值用于初始化累积。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
另请参见 accumulate
, cumsum!
, cumprod!
。
示例
julia> x = [1, 0, 2, 0, 3];
julia> y = rand(5);
julia> accumulate!(+, y, x);
julia> y
5-element Vector{Float64}:
1.0
1.0
3.0
3.0
6.0
julia> A = [1 2 3; 4 5 6];
julia> B = similar(A);
julia> accumulate!(-, B, A, dims=1)
2×3 Matrix{Int64}:
1 2 3
-3 -3 -3
julia> accumulate!(*, B, A, dims=2, init=10)
2×3 Matrix{Int64}:
10 20 60
40 200 1200
Base.cumprod
— Functioncumprod(A; dims::Integer)
沿着维度 dim
的累积乘积。另请参见 cumprod!
,以使用预分配的输出数组,这样可以提高性能并控制输出的精度(例如,避免溢出)。
示例
julia> a = Int8[1 2 3; 4 5 6];
julia> cumprod(a, dims=1)
2×3 Matrix{Int64}:
1 2 3
4 10 18
julia> cumprod(a, dims=2)
2×3 Matrix{Int64}:
1 2 6
4 20 120
cumprod(itr)
迭代器的累积乘积。
另见 cumprod!
, accumulate
, cumsum
。
在非数组迭代器上使用 cumprod
至少需要 Julia 1.5。
示例
julia> cumprod(fill(1//2, 3))
3-element Vector{Rational{Int64}}:
1//2
1//4
1//8
julia> cumprod((1, 2, 1, 3, 1))
(1, 2, 2, 6, 6)
julia> cumprod("julia")
5-element Vector{String}:
"j"
"ju"
"jul"
"juli"
"julia"
Base.cumprod!
— Functioncumprod!(B, A; dims::Integer)
沿着维度 dims
计算 A
的累积乘积,并将结果存储在 B
中。另见 cumprod
。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
cumprod!(y::AbstractVector, x::AbstractVector)
向量 x
的累积乘积,结果存储在 y
中。另见 cumprod
。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
Base.cumsum
— Functioncumsum(A; dims::Integer)
沿着维度 dims
的累积和。另请参见 cumsum!
,以使用预分配的输出数组,既可以提高性能,也可以控制输出的精度(例如,避免溢出)。
示例
julia> a = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> cumsum(a, dims=1)
2×3 Matrix{Int64}:
1 2 3
5 7 9
julia> cumsum(a, dims=2)
2×3 Matrix{Int64}:
1 3 6
4 9 15
返回数组的 eltype
对于小于系统字大小的有符号整数为 Int
,对于小于系统字大小的无符号整数为 UInt
。为了保留小有符号或无符号整数数组的 eltype
,应使用 accumulate(+, A)
。
julia> cumsum(Int8[100, 28])
2-element Vector{Int64}:
100
128
julia> accumulate(+,Int8[100, 28])
2-element Vector{Int8}:
100
-128
在前一种情况下,整数被扩展到系统字大小,因此结果为 Int64[100, 128]
。在后一种情况下,没有发生这样的扩展,整数溢出导致结果为 Int8[100, -128]
。
cumsum(itr)
迭代器的累积和。
另请参见 accumulate
以应用其他函数而非 +
。
在非数组迭代器上使用 cumsum
至少需要 Julia 1.5。
示例
julia> cumsum(1:3)
3-element Vector{Int64}:
1
3
6
julia> cumsum((true, false, true, false, true))
(1, 1, 2, 2, 3)
julia> cumsum(fill(1, 2) for i in 1:3)
3-element Vector{Vector{Int64}}:
[1, 1]
[2, 2]
[3, 3]
Base.cumsum!
— Functioncumsum!(B, A; dims::Integer)
对 A
沿着维度 dims
进行累积求和,将结果存储在 B
中。另见 cumsum
。
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
Base.diff
— Functiondiff(A::AbstractVector)
diff(A::AbstractArray; dims::Integer)
在向量或多维数组 A
上的有限差分算子。在后者的情况下,需要通过 dims
关键字参数指定操作的维度。
对于维度高于 2 的数组,diff
至少需要 Julia 1.1。
示例
julia> a = [2 4; 6 16]
2×2 Matrix{Int64}:
2 4
6 16
julia> diff(a, dims=2)
2×1 Matrix{Int64}:
2
10
julia> diff(vec(a))
3-element Vector{Int64}:
4
-2
12
Base.repeat
— Functionrepeat(A::AbstractArray, counts::Integer...)
通过在每个维度上重复数组 A
指定次数来构造一个数组,次数由 counts
指定。
另见: fill
, Iterators.repeated
, Iterators.cycle
.
示例
julia> repeat([1, 2, 3], 2)
6-element Vector{Int64}:
1
2
3
1
2
3
julia> repeat([1, 2, 3], 2, 3)
6×3 Matrix{Int64}:
1 1 1
2 2 2
3 3 3
1 1 1
2 2 2
3 3 3
repeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))
通过重复 A
的条目构造一个数组。inner
的第 i 个元素指定 A
的第 i 个维度的单个条目应重复的次数。outer
的第 i 个元素指定沿 A
的第 i 个维度的切片应重复的次数。如果省略 inner
或 outer
,则不执行重复。
示例
julia> repeat(1:2, inner=2)
4-element Vector{Int64}:
1
1
2
2
julia> repeat(1:2, outer=2)
4-element Vector{Int64}:
1
2
1
2
julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
4×6 Matrix{Int64}:
1 2 1 2 1 2
1 2 1 2 1 2
3 4 3 4 3 4
3 4 3 4 3 4
repeat(c::AbstractChar, r::Integer) -> String
将字符重复 r
次。这可以通过调用 c^r
来等效实现。
示例
julia> repeat('A', 3)
"AAA"
Base.rot180
— Functionrot180(A)
将矩阵 A
旋转 180 度。
示例
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> rot180(a)
2×2 Matrix{Int64}:
4 3
2 1
rot180(A, k)
将矩阵 A
旋转 180 度,整数 k
次。如果 k
是偶数,这相当于一个 copy
。
示例
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> rot180(a,1)
2×2 Matrix{Int64}:
4 3
2 1
julia> rot180(a,2)
2×2 Matrix{Int64}:
1 2
3 4
Base.rotl90
— Functionrotl90(A)
将矩阵 A
向左旋转 90 度。
示例
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> rotl90(a)
2×2 Matrix{Int64}:
2 4
1 3
rotl90(A, k)
将矩阵 A
逆时针旋转 90 度,旋转 k
次。如果 k
是四的倍数(包括零),这相当于一个 copy
。
示例
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> rotl90(a,1)
2×2 Matrix{Int64}:
2 4
1 3
julia> rotl90(a,2)
2×2 Matrix{Int64}:
4 3
2 1
julia> rotl90(a,3)
2×2 Matrix{Int64}:
3 1
4 2
julia> rotl90(a,4)
2×2 Matrix{Int64}:
1 2
3 4
Base.rotr90
— Functionrotr90(A)
将矩阵 A
右旋转 90 度。
示例
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> rotr90(a)
2×2 Matrix{Int64}:
3 1
4 2
rotr90(A, k)
将矩阵 A
顺时针旋转 90 度 k
次。如果 k
是四的倍数(包括零),这相当于一个 copy
。
示例
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> rotr90(a,1)
2×2 Matrix{Int64}:
3 1
4 2
julia> rotr90(a,2)
2×2 Matrix{Int64}:
4 3
2 1
julia> rotr90(a,3)
2×2 Matrix{Int64}:
2 4
1 3
julia> rotr90(a,4)
2×2 Matrix{Int64}:
1 2
3 4
Base.mapslices
— Functionmapslices(f, A; dims)
通过在每个切片 A[..., :, ..., :, ...]
上应用函数 f
,转换数组 A
的给定维度,其中在 dims
中的每个 d
位置都有一个冒号。结果沿着其余维度连接。
例如,如果 dims = [1,2]
且 A
是 4 维的,则 f
在 x = A[:,:,i,j]
上被调用,针对所有的 i
和 j
,并且 f(x)
在结果 R
中变为 R[:,:,i,j]
。
另见 eachcol
或 eachslice
,与 map
或 stack
一起使用。
示例
julia> A = reshape(1:30,(2,5,3))
2×5×3 reshape(::UnitRange{Int64}, 2, 5, 3) with eltype Int64:
[:, :, 1] =
1 3 5 7 9
2 4 6 8 10
[:, :, 2] =
11 13 15 17 19
12 14 16 18 20
[:, :, 3] =
21 23 25 27 29
22 24 26 28 30
julia> f(x::Matrix) = fill(x[1,1], 1,4); # 返回一个 1×4 矩阵
julia> B = mapslices(f, A, dims=(1,2))
1×4×3 Array{Int64, 3}:
[:, :, 1] =
1 1 1 1
[:, :, 2] =
11 11 11 11
[:, :, 3] =
21 21 21 21
julia> f2(x::AbstractMatrix) = fill(x[1,1], 1,4);
julia> B == stack(f2, eachslice(A, dims=3))
true
julia> g(x) = x[begin] // x[end-1]; # 返回一个数字
julia> mapslices(g, A, dims=[1,3])
1×5×1 Array{Rational{Int64}, 3}:
[:, :, 1] =
1//21 3//23 1//5 7//27 9//29
julia> map(g, eachslice(A, dims=2))
5-element Vector{Rational{Int64}}:
1//21
3//23
1//5
7//27
9//29
julia> mapslices(sum, A; dims=(1,3)) == sum(A; dims=(1,3))
true
注意,在 eachslice(A; dims=2)
中,指定的维度是切片中 没有 冒号的那个维度。这是 view(A,:,i,:)
,而 mapslices(f, A; dims=(1,3))
使用的是 A[:,i,:]
。函数 f
可以在切片中修改值,而不影响 A
。
Base.eachrow
— Functioneachrow(A::AbstractVecOrMat) <: AbstractVector
创建一个 RowSlices
对象,它是矩阵或向量 A
的行向量。行切片作为 AbstractVector
视图返回。
有关反向操作,请参见 stack
(rows; dims=1)
。
另请参见 eachcol
、eachslice
和 mapslices
。
此函数至少需要 Julia 1.1。
在 Julia 1.9 之前,这返回一个迭代器。
示例
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> s = eachrow(a)
2-element RowSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:
[1, 2]
[3, 4]
julia> s[1]
2-element view(::Matrix{Int64}, 1, :) with eltype Int64:
1
2
Base.eachcol
— Functioneachcol(A::AbstractVecOrMat) <: AbstractVector
创建一个 ColumnSlices
对象,它是矩阵或向量 A
的列向量。列切片作为 AbstractVector
视图返回。
对于反向操作,请参见 stack
(cols)
或 reduce(
hcat
, cols)
。
另请参见 eachrow
、eachslice
和 mapslices
。
此函数至少需要 Julia 1.1。
在 Julia 1.9 之前,这返回一个迭代器。
示例
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]
julia> s[1]
2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
1
3
Base.eachslice
— Functioneachslice(A::AbstractArray; dims, drop=true)
创建一个 Slices
对象,该对象是 A
的 dims
维度上的切片数组,返回选择 A
中其他维度所有数据的视图。dims
可以是一个整数或一个整数元组。
如果 drop = true
(默认值),外部的 Slices
将丢弃内部维度,维度的顺序将与 dims
中的顺序匹配。如果 drop = false
,则 Slices
将具有与基础数组相同的维度,内部维度的大小为 1。
请参见 stack
(slices; dims)
以获取 eachslice(A; dims::Integer)
的逆操作。
另请参见 eachrow
、eachcol
、mapslices
和 selectdim
。
此函数至少需要 Julia 1.1。
在 Julia 1.9 之前,这返回一个迭代器,并且仅支持单个维度 dims
。
示例
julia> m = [1 2 3; 4 5 6; 7 8 9]
3×3 Matrix{Int64}:
1 2 3
4 5 6
7 8 9
julia> s = eachslice(m, dims=1)
3-element RowSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
julia> s[1]
3-element view(::Matrix{Int64}, 1, :) with eltype Int64:
1
2
3
julia> eachslice(m, dims=1, drop=false)
3×1 Slices{Matrix{Int64}, Tuple{Int64, Colon}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, 2}:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Combinatorics
Base.invperm
— Functioninvperm(v)
返回 v
的逆排列。如果 B = A[v]
,则 A == B[invperm(v)]
。
另请参见 sortperm
, invpermute!
, isperm
, permutedims
。
示例
julia> p = (2, 3, 1);
julia> invperm(p)
(3, 1, 2)
julia> v = [2; 4; 3; 1];
julia> invperm(v)
4-element Vector{Int64}:
4
1
3
2
julia> A = ['a','b','c','d'];
julia> B = A[v]
4-element Vector{Char}:
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> B[invperm(v)]
4-element Vector{Char}:
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
Base.isperm
— Functionisperm(v) -> Bool
如果 v
是一个有效的排列,则返回 true
。
示例
julia> isperm([1; 2])
true
julia> isperm([1; 3])
false
Base.permute!
— Methodpermute!(v, p)
就地对向量 v
进行置换,按照置换 p
。不会检查 p
是否为一个置换。
要返回一个新的置换,请使用 v[p]
。这通常比 permute!(v, p)
更快;使用 u .= @view v[p]
写入预分配的输出数组甚至更快。(尽管 permute!
就地覆盖 v
,但它在内部需要一些分配来跟踪哪些元素已被移动。)
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
另请参见 invpermute!
。
示例
julia> A = [1, 1, 3, 4];
julia> perm = [2, 4, 3, 1];
julia> permute!(A, perm);
julia> A
4-element Vector{Int64}:
1
4
3
1
Base.invpermute!
— Functioninvpermute!(v, p)
与 permute!
类似,但应用给定排列的逆排列。
请注意,如果您有一个预分配的输出数组(例如 u = similar(v)
),那么使用 u[p] = v
会更快。 (invpermute!
在内部会分配数据的副本。)
当任何被修改的参数与其他参数共享内存时,行为可能会出乎意料。
示例
julia> A = [1, 1, 3, 4];
julia> perm = [2, 4, 3, 1];
julia> invpermute!(A, perm);
julia> A
4-element Vector{Int64}:
4
1
3
1
Base.reverse
— Methodreverse(A; dims=:)
沿着维度 dims
反转 A
,其中 dims
可以是一个整数(单个维度)、一个整数元组(多个维度)或 :
(沿所有维度反转,默认为此)。另见 reverse!
进行就地反转。
示例
julia> b = Int64[1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> reverse(b, dims=2)
2×2 Matrix{Int64}:
2 1
4 3
julia> reverse(b)
2×2 Matrix{Int64}:
4 3
2 1
在 Julia 1.6 之前,reverse
仅支持单个整数 dims
。
Base.reverseind
— Functionreverseind(v, i)
给定索引 i
在 reverse(v)
中,返回 v
中对应的索引,以便满足 v[reverseind(v,i)] == reverse(v)[i]
。 (在 v
包含非 ASCII 字符的情况下,这可能并不简单。)
示例
julia> s = "Julia🚀"
"Julia🚀"
julia> r = reverse(s)
"🚀ailuJ"
julia> for i in eachindex(s)
print(r[reverseind(r, i)])
end
Julia🚀
Base.reverse!
— Functionreverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
reverse
的就地版本。
示例
julia> A = Vector(1:5)
5-element Vector{Int64}:
1
2
3
4
5
julia> reverse!(A);
julia> A
5-element Vector{Int64}:
5
4
3
2
1