Julia预分配数组与MATLAB预分配数组

use*_*911 2 julia

在MATLAB中,建议预先分配数组,否则数组会在迭代过程中改变大小。假设该建议也对朱莉娅有所帮助,我想知道如何做到这一点。

在MATLAB中,以下代码预分配5 x 10数组:

A = nan(5,10)
Run Code Online (Sandbox Code Playgroud)

在朱莉娅中将如何获得相同的东西?

hck*_*ckr 8

A = nan(5,10)不仅分配了doubles 的数组,而且还使用NaNs 初始化了数组的条目(尽管MATLAB可能无法真正填充该数组)。

简短的答案是A = nan(5, 10)在MATLAB中在语义上A = fill(NaN, 5, 10)在Julia中等效。

长的答案是,在Julia中,您有许多选项和更多的控件可用于数组分配和初始化。

无需初始化的数组分配

在Julia中,可以分配一个数组或一个矩阵(它是一个2D数组),而条目未初始化。

# Allocate an "uninitialized" m-by-n `Float64` (`double`) matrix
A = Array{Float64, 2}(undef, m, n)
# or equivalently
A = Matrix{Float64}(undef, m, n) # `Matrix{T}` is equivalent to `Array{T, 2}`
# you do not need to type dimensionality even with `Array`,
# the dimensionality will be inferred from the number of parameters
A = Array{Float64}(undef, m, n)

# You can do the same for arrays of different dimensions or other types
A = Array{Float64, 3}(undef, m, n, k) # 3D `Float64` array of size m*n*k
A = Array{Int64}(undef, m) # 1D `Int64` array
A = Vector{Float32}(undef, m) # 1D `Float32` (i.e. `single`) array. `Vector{T} === Array{T, 1}`
Run Code Online (Sandbox Code Playgroud)

无需使用其他数组进行初始化即可进行数组分配

在Julia中,您可以使用该函数similar使用另一个矩阵的类型,元素类型和维数信息来分配数组,并且不对其进行初始化。

A = zeros(UInt8, m, n)
B = similar(A) # allocates the same type of array (dense, sparse, etc.) with the same element type, and the same dimensions as `A`

C = similar(A, Float64) # allocates the same type of array with the same dimensions as `A` but with the element type of `Float64`
Run Code Online (Sandbox Code Playgroud)

分配一个空数组

您可以使用上面传递的数组构造语法0作为维度,也可以简单T[]地创建一个类型为空的数组T

A = Float64[]
Run Code Online (Sandbox Code Playgroud)

初始化的数组分配

# Allocate a `Float64` array and fill it with 0s
A = zeros(m, n) # m-by-n Float64 matrix filled with zeros
A = zeros(m, n, k, l) # a 4D Float64 array filled with zeros

# similarly to fill with `Float64` 1s
A = ones(m, n)
A = ones(m) # a 1D array of size `m`
A = ones(m, 1) # an `m`-by-1 2D array

# you can use these functions with other types as well
A = zeros(Float32, m, n)
A = ones(UInt8, m, n, k)


# you can allocate an array/matrix and fill it with any value you like using `fill`
# the type is inferred by the value entered
A = fill(4.0, (m, n)) # m-by-n matrix filled with `4.0`
A = fill(0.50f, m, n, k) # a 3D Float32 array filled `0.5`s

# so to fill with `NaN`s you can use
A = fill(NaN, m, n)

# random initialization
A = rand(m, n) # m-by-n Float64 matrix with uniformly distributed values in `[0,1)`
A = rand(Float32, m) # an array of size `m` with uniformly distributed values in `[0,1)`

A = randn(m, n) # the same as `rand` but with normally distributed values

# you can initialize the array with values randomly (uniform) picked from a collection
A = rand([1, 5, 7], m, n) # values will be picked from the array `[1,5,7]`
Run Code Online (Sandbox Code Playgroud)

您可以使用fill!(A, value)或简单地使用A .= value相同的值来填充已经分配的数组。如果导入模块Random,则可以使用rand!randn!用随机值填充已经分配的数组。由于可以避免分配,因此这可能会给您带来显着的性能优势。

您可以查看Julia文档的“多维数组”部分,以了解有关Julia中数组的更多信息。


笔记

在Julia中,您无法更改内置的 多维(非1D)尺寸Array

A = zeros(5,5)
A[6,5] = 2 # bounds error
Run Code Online (Sandbox Code Playgroud)

但是您可以将push!一维化 Array。这将有效地调整数组的大小。

julia> A = Int[];
julia> push!(A, 1);
julia> push!(A, 2, 3);
julia> A
3-element Array{Int64,1}:
 1
 2
 3
Run Code Online (Sandbox Code Playgroud)

  • 很棒的清单!只是分配空数组的补充:还有 [`sizehint!`](https://docs.julialang.org/en/v1/base/collections/#Base.sizehint!),如果您知道,它可以提高性能从一开始就结束容量。 (2认同)