Engee 中的数组、向量和矩阵
导言
在*Engee*中,数组、向量和矩阵用于处理数据、参数和复杂结构。这些结构由Julia 语言实现,可以高效地存储和处理数值信息,包括计算结果、信号和模型参数。本文将讨论它们各自的特点。
在 Julia 中,数组、矢量和矩阵的元素编号以 "1 "开头,而不是像其他语言那样以 "0 "开头。最后一个元素的索引为 "end"。这与数学的传统是一致的,数学的索引也是从 1 开始。例如,数组 a = [1, 2, 3] 的第一个元素用 a[1] 访问,最后一个元素用 `a[end]`访问。详见下文。
|
数组*是一种通用的多维容器,可以包含任何类型的元素。Julia 中的数组支持任意维数,是存储和处理数据的多功能工具:
A = rand(2, 2, 3)
输出
2×2×3 Array{Float64, 3}:
[:, :, 1] =
0.159525 0.787948
0.358068 0.124023
[:, :, 2] =
0.228296 0.292929
0.712896 0.0253828
[:, :, 3] =
0.3547 0.837655
0.474441 0.201402
数组有动态和静态之分:
-
*动态数组*是在程序执行过程中其大小可能发生变化的数组。这些数组存储在内存中,可能会进行扩展,这使得它们更加灵活,但对于计算密集型任务来说,却不是最佳选择。
例如
dynamic_array = [1, 2, 3] dynamic_array[2] = 5 # Присваивание значения push!(dynamic_array, 4) # Добавление элемента deleteat!(dynamic_array, 3) # Удаление элемента с индексом 3
输出
4-element Vector{Int64}: 1 5 3 4
-
*静态数组*是具有固定大小的数组,大小在创建阶段设定。它们以连续数据块的形式存储在内存中,这样可以最大限度地减少内存管理开销,从而更快地执行操作。
当静态数组的大小小于 100-200 个元素时,其效率较高。如果大小大于 100-200 个元素,则通常使用动态数组。 在 Julia 中,静态数组由 StaticArrays.jl 包提供。因此,要使用静态数组,需要使用
using StaticArrays
命令连接 该软件包。示例
using StaticArrays static_array = @SVector [1, 2, 3]
输出
3-element SVector{3, Int64} with indices SOneTo(3): 1 2 3
代码中使用了一个宏脚注:
@SVector
,用于创建一个固定大小的静态一维数组(向量)。静态数组还有其他有用的宏:静态数组宏_。
-
@SVector
- 创建一个固定大小的不可变静态向量。例如`@SVector [1, 2, 3]`。 -
@MVector
- 创建一个固定大小的可变静态向量。示例`@MVector [1, 2, 3]`. -
@SMatrix
- 创建一个固定大小的可变静态矩阵。示例`@SMatrix [1 2; 3 4]`. -
@MMatrix
- 创建一个固定大小的可变静态矩阵。示例`@MMatrix [1 2; 3 4]`. -
@SizedArray
- 将普通数组转换为固定大小的静态数组。示例`@SisedArray rand(2, 2)`. -
@SArray
- 创建一个固定大小的普通静态数组,可以是向量、矩阵或高维数组。示例`@SArray rand(2, 2, 2, 2)`. -
@MArray
- 创建一个通用的可变静态数组。示例`@MArray rand(2, 2, 2, 2)`. -
@StaticArray
- 一个通用宏,用于创建任意形状的不可变数组。示例`@StaticArray rand(2, 2, 2)`. -
@MutableStaticArray
是创建可变静态数组的通用宏。示例`@MutableStaticArray rand(2, 2)`. -
@zeros
- 创建一个充满 0 的静态数组。示例`@zeros(SVector, 3)` 创建一个包含三个零的向量。 -
@ones
- 创建一个充满 1 的静态数组。示例`@ones(SMatrix, 2, 2)` 创建一个 2×2 的 1 矩阵。 -
@fill
- 创建一个充满给定值的静态数组。示例@fill(SVector,3,42)`创建一个由三个元素组成、值为 42 的矢量。 -
@static
- 通过应用静态数组的属性,在编译阶段优化代码块的执行。示例
@static if length(SVector(1, 2, 3)) == 3 println("Размер 向量а равен 3") end
-
与 C++ 不同,Julia 中的数组可以存储不同类型的元素。如果元素类型可以简化为一种通用类型(例如 "有理数 "和 "复数"),Julia 将自动执行类型转换。例如
如果元素类型无法还原为一种通用类型(例如数字和字符串),Julia 会将数组转换为
这使得 Julia 中的数组变得灵活,但值得注意的是,使用 |
矢量*是一个一维数组,是使用索引访问的元素序列。在 Julia 中,矢量可以创建为*矢量列*或*矢量字符串*,但它们的语法和数据类型有所不同:
-
列向量使用逗号或列条目创建:
v = [1, 2, 3] # Вектор-столбец
或
v = [1 2 3] # Вектор-столбец
输出
3-element Vector{Int64}: 1 2 3
-
Julia 没有单独的矢量字符串类型。取而代之的是,数字字符串被表示为维度为 1 × N 的矩阵:
r = [1 2 3] # Матрица 1 × 3
输出
1×3 Matrix{Int64}: 1 2 3
在 Julia 中,数组中的分隔符定义了数组的结构:
|
矩阵(Matrix)是一个二维数组,代表一个按行和列排列的数字或其他对象的表格。在 Julia 中,矩阵是以二维数组的形式创建的:
M = [1 2 3; 4 5 6]
输出
2×3 Matrix{Int64}:
1 2 3
4 5 6
在 Julia 中,矢量和矩阵的分离可以有效地组织内存中的数据,这对快速数值计算非常重要。矢量使用一维存储,因此更容易处理数据序列,而矩阵则以二维形式组织,因此更容易执行线性代数(乘法和转置)。这种分离有助于优化缓存内存和 CPU 资源的使用,提高计算效率。
数组、矢量和矩阵之间的区别
维度:
-
数组是具有任意维数的容器。数组有任意维数,例如,
size(A)
可以返回 (2
,2
,3
)。 -
向量是一维数组。向量总是一维的,函数
size(v)
返回元组(n,)
,其中n
是向量的长度。 -
矩阵是一个二维数组。矩阵的维数为二,
size(M)
返回`(n, m)`元组,其中`n`是行数,`m`是列数。
元组是一种不可变的数据结构,可以包含不同类型的多个元素。在 Julia 中,元组用于表示逻辑上相关但无需修改的值。例如,函数`size()`的结果总是以元组的形式返回。 与向量和矩阵不同,元组不是数组,也不是用来执行算术运算的。它有固定数量的元素和不可变的结构,因此在从函数返回多个值或传递参数时非常有用。 |
-
实施特点
-
处理数组的方法和函数适用于向量和矩阵。不过,每种类型的数据都有不同的优化算法。
-
在 Julia 中,矢量和矩阵是数组的特例,其中矢量的维度为 "1",矩阵的维度为 "2"。
-
-
初始化和语法
-
可通过 Array 函数或使用生成器(表达式为"[… for …]")创建任意维数的数组。例如,对于 Array:
A = Array{Float64}(undef, 2, 2, 3)
这里的 undef 是一个关键字,用于创建一个数组而不初始化元素。这意味着将为数组分配内存,但其元素的值将保持未定义(可能是随机的)。
使用生成器的示例
array = [i^2 for i in 1:5] # Каждый элемент массива – квадрат числа от 1 до 5
-
以一维数组的形式创建向量,使用逗号枚举元素:
v = [1, 2, 3]
-
矩阵以分号分隔行 (
;
),行中的元素以空格或制表符分隔:M = [1 2 3; 4 5 6]
-
-
内存存储:
-
具有大量维度的阵列使用更通用的存储方法,这会增加操作的开销。
-
上述差异形成了特定的应用领域:
-
阵列用于模拟更复杂的数据:三维模型、图像阵列或多维时间序列。
-
矢量最常用于一维数据:时间序列、坐标、信号。
-
矩阵表示二维结构:图像、表格、线性方程组。
处理数组、矢量和矩阵的基本功能
Julia 提供了大量处理数组(包括矢量和矩阵)的函数。有关这些函数及其签名的更多信息,请访问Arrays 。
标有`*`的函数不是标准库的一部分。要使用它们,请安装相应的 Julia 软件包:
导入 "和 "使用 "操作符以及软件包名称可用于访问此类函数的元素。更多信息,请访问使用 Julia 软件包 。 |
以下是基本函数列表,附有简要说明和示例:
创建
功能名称 |
说明 |
示例 |
|
创建一个元素等于零的数组。 创建对象的类型取决于传递的参数:一维数组(向量)、二维数组(矩阵)或多维数组。 |
[源代码,julia]. zeros(3) zeros(2, 2) zeros(2, 2, 3) 这里
|
|
创建元素等于 1 的数组。 创建对象的类型取决于传递的参数:一维数组(向量)、二维数组(矩阵)或多维数组。 |
[源代码,julia]. ones(3) ones(2, 2) ones(2, 2, 3) 这里
|
rand`。 |
创建一个数组,其中包含在"[0, 1) "区间内均匀分布的随机数。创建对象的类型取决于传递的参数:一维数组(向量)、二维数组(矩阵)或多维数组。 |
[源代码,julia]. rand(3) rand(2, 2) rand(2, 2, 3) 这里
|
填充 |
创建一个填充指定值的数组。创建对象的类型取决于传递的参数:一维数组(向量)、二维数组(矩阵)或多维数组。 |
[源代码,julia]. fill(7, 3) fill(5, 2, 2) fill(75, 2, 2, 3) 这里:
|
收集 |
通过转换给定的范围或迭代对象创建数组。创建对象的类型取决于所使用的输入。 |
[源代码,julia]. collect(1:3) collect(reshape(1:4, 2, 2)) collect(reshape(1:12, 2, 2, 3)) 这里:
|
结构变化
功能名称 |
说明 |
示例 |
push!"。 |
在一维数组(向量)的末尾添加一个元素。仅适用于可修改(动态)数组。 末尾索引也可用于添加元素 (数组索引). |
[源代码,julia]. v = [1, 2, 3] push!(v, 4) m = reshape(1:6, 2, 3) # push! нельзя применить к матрице или многомерному массиву. 这里:
|
pop!`。 |
从一维数组(向量)中删除并返回最后一个元素。仅适用于可修改(动态)数组。 |
[源代码,julia]. v = [1, 2, 3, 4] last_element = pop!(v) m = reshape(1:6, 2, 3) # pop! нельзя применить к матрице или многомерному массиву. 这里
|
|
在一维数组(向量)的指定位置插入一个元素。仅适用于可修改(动态)数组。 |
[源代码,julia]. v = [1, 2, 4, 5] insert!(v, 3, 3) m = reshape(1:6, 2, 3) # insert! нельзя применить к матрице или многомерному массиву. 这里
|
删除 |
从一维数组(向量)中删除指定索引处的元素。仅适用于可修改(动态)数组。 |
[源代码,julia]. v = [1, 2, 3, 4, 5] deleteat!(v, 3) m = reshape(1:6, 2, 3) # deleteat! нельзя применить к матрице или многомерному массиву. 这里
|
使用维数_
功能名称 |
说明 |
示例 |
|
以元组形式返回数组、矩阵或向量的大小,其中每个值都对应特定维度的大小。 |
[源代码,朱莉娅]. v = [1, 2, 3] size(v) m = reshape(1:6, 2, 3) size(m) a = zeros(2, 2, 3) size(a) 这里
|
|
改变一维数组(向量)的大小。如果新的大小大于当前的大小,新的元素将以默认值 `0.0`初始化。如果小于当前大小,数组将被修剪为指定大小。 |
[源代码,julia]. v = [1, 2, 3] resize!(v, 5) resize!(v, 2) m = reshape(1:6, 2, 3) # resize! нельзя применить к матрице или многомерному массиву. 这里
|
长度 |
返回数组、向量或矩阵中元素的总数,与它们的维数无关。 |
[源代码,julia]. v = [1, 2, 3] length(v) m = reshape(1:6, 2, 3) length(m) a = zeros(2, 2, 3) length(a) 这里
|
|
返回数组、向量或矩阵的维数。 |
[源代码,julia]. v = [1, 2, 3] ndims(v) m = reshape(1:6, 2, 3) ndims(m) a = zeros(2, 2, 3) ndims(a) 这里
|
|
改变数组、矩阵或向量的维度,将其转换为具有指定行数和列数的新数组。新数组的元素数必须与原始数组的元素数一致。 |
v = [1, 2, 3, 4, 5, 6] m = reshape(v, 2, 3) a = [1, 2, 3, 4, 5, 6, 7, 8, 9] b = reshape(a, 3, 3) c = reshape(a, 1, 9) 这里:
|
线性代数
函数名 |
说明 |
示例 |
转置 |
返回行列互换的数组或矩阵。对于一维数组(向量),结果取决于其方向。 |
[源代码,julia]. v = [1, 2, 3] vt = transpose(v) m = [1 2; 3 4; 5 6] mt = transpose(m) 这里
|
* |
计算正方形矩阵的行列式。它是 LinearAlgebra 软件包的一部分(需要安装软件包)。 行列式是一个标量,用于描述矩阵的特性(如可逆性)。 |
m1 = [2 3; 1 4] det(m1) m2 = [1 2 3; 4 5 6; 7 8 10] det(m2) m3 = [0 1; 2 3] det(m3) 此处:
|
|
计算正方形矩阵的逆矩阵。逆矩阵只适用于行列式不为零的矩阵,即可逆矩阵。 即使源矩阵的值是整数("矩阵{Int64}"),"inv "函数也会返回一个 "矩阵{Float64}"类型的逆矩阵。 |
[源,julia]。 m1 = [2 3; 1 4] inv(m1) m2 = [1 2 3; 0 1 4; 5 6 0] inv(m2) m3 = [1 2; 3 4] inv(m3) 这里:
|
* |
计算矩阵的特征值和向量。例如
|
[源代码,julia]. m1 = [4 1; 2 3] eigvals(m1) eigvecs(m1) m2 = [1 2 3; 4 5 6; 7 8 9] eigvals(m2) eigvecs(m2) 这里:
|
norm`。 |
计算向量或矩阵的规范。 常模是衡量向量或矩阵 "大小 "的数字特征。默认情况下,计算的是欧氏常模。 |
v = [3, 4] norm(v) m = [1 2; 3 4] norm(m) norm(v, 1) # 3 + 4 = 7.0 norm(m, Inf) #√30 ≈ 5.477 这里:
|
检查
功能名称 |
说明 |
示例 |
|
检查数组、向量或矩阵是否为空。如果对象为空,则返回 |
# Проверка пустого и непустого 向量а v1 = [] v2 = [1, 2, 3] isempty(v1) isempty(v2) # Проверка пустой и непустой матрицы m1 = reshape([], 0, 0) m2 = [1 2; 3 4] isempty(m1) isempty(m2) # Проверка пустого и непустого массива a1 = Int[] a2 = [1, 2, 3, 4] isempty(a1 isempty(a2) 此处:
|
|
检查对象是否为空。如果对象为空,则返回 支持数值类型以及数组、矩阵和向量(在 Julia 中,如果对象的所有元素都为零,则该对象为空)。 |
[源代码,julia]. # Проверка числа x = 0 y = 5 iszero(x) # true iszero(y) # false # Проверка 向量а v1 = [0, 0, 0] v2 = [0, 1, 0] iszero(v1) # true iszero(v2) # false # Проверка матрицы m1 = zeros(2, 2)нулями m2 = [1 0; 0 0]элементом iszero(m1) # true iszero(m2) # false # Проверка многомерного массива a1 = zeros(2, 2, 2) a2 = reshape([1, 0, 0], 1, 3) iszero(a1) # true iszero(a2) # false 这里 用于数字:
对于向量
对于矩阵
对于多维数组:
|
|
检查矩阵是否对称。如果矩阵等于其转置副本,则返回 |
[源代码,julia]. # Симметричная 矩阵 m1 = [1 2 3; 2 4 5; 3 5 6] issymmetric(m1) # true # Несимметричная 矩阵 m2 = [1 0 0; 0 4 5; 3 5 6] issymmetric(m2) # false # Квадратная, но несимметричная 矩阵 m3 = [1 2; 3 4] issymmetric(m3) # false # Несимметричная прямоугольная 矩阵 m4 = [1 2; 2 3; 3 4] issymmetric(m4) # false 此处:
|
变换.
函数名称 |
说明 |
示例 |
|
将矩阵或多维数组转换为向量。它会返回一个一维数组,其中的元素取自原始矩阵或数组的列。如果参数已经是一个向量,则返回值不变。 |
[源代码,julia]. # Преобразование матрицы в 向量 m = [1 2; 3 4] v1 = vec(m) # [1, 3, 2, 4] # Преобразование трехмерного массива в 向量 a = zeros(2, 2, 2) a[:, :, 1] .= [1 2; 3 4] a[:, :, 2] .= [5 6; 7 8] v2 = vec(a) # [1, 3, 2, 4, 5, 7, 6, 8] # Преобразование 向量а (без изменений) v = [1, 2, 3] v3 = vec(v) # [1, 2, 3]
|
|
重新排列多维数组的测量值(轴)。 可以在不改变数据本身的情况下改变测量的顺序,创建一个具有重新排列的轴的新数组。 |
这里:
|
|
数组的横向和纵向连接(并集)。
|
[源代码,julia]. # Горизонтальное объединение (hcat) v1 = [1, 2, 3] v2 = [4, 5, 6] h_result = hcat(v1, v2) # Вертикальное объединение (vcat) v3 = [7, 8, 9] v_result = vcat(v1, v3) # Объединение матриц m1 = [1 2; 3 4] m2 = [5 6; 7 8] hcat_result = hcat(m1, m2) vcat_result = vcat(m1, m2) 这里:
|
复制 |
创建数组、向量或矩阵的独立副本。对副本所做的更改不会影响原始对象,反之亦然。 |
[源代码,朱莉娅]. v = [1, 2, 3] v_copy = copy(v) v[1] = 10 # Изменяем оригинал println(v) # [10, 2, 3] println(v_copy) # [1, 2, 3] 这里
|
|
创建数组的深度副本,递归复制所有嵌套结构。对副本的修改不会影响原数组。在 Julia 中,默认赋值传递的是对象引用而不是值。如果需要创建一个独立的副本,有两种方法:
|
[源代码,朱莉娅]. A = [[1, 2], [3, 4]] B = copy(A) # Неглубокая копия C = deepcopy(A) # Глубокая копия B[1][1] = 99 println(A) # [[99, 2], [3, 4]] — A изменился, потому что B и A связаны println(C) # [[1, 2], [3, 4]] — Глубокая копия не изменилась 这里:
|
广播 |
允许对数组元素进行自动大小匹配(广播)操作。详情请参见此处。 |
[源代码,julia]。 # Пример с 向量ом v = [1, 2, 3] v_squared = broadcast(x -> x^2, v) # Пример с матрицей m = [1 2; 3 4] m_doubled = broadcast(x -> x * 2, m) # Пример с разными размерами массивов a = [1, 2, 3] b = [4, 5] result = broadcast(+, a, b') 此处:
|
使用数组的适当性
数组是一种方便灵活的数据处理工具,但 Julia 的其他结构可能更适合某些任务。详见下文。
何时推荐使用数组
-
通过索引快速访问元素 - 数组在内存中按顺序存储元素,允许通过索引即时访问任何元素。例如,
ar[3]
将立即返回数组的第三个元素。这被称为 随机存取(随机存取),运行时间为O(1)
(无论输入数据的大小如何,操作所需的时间不变,即无论数组有多大,按索引访问元素所需的时间相同)。 -
在末尾高效添加和删除 - 如果需要经常在数组末尾添加或删除元素,那么可以使用`push!
(添加一个元素)和`pop!
(删除最后一个元素)函数。这些操作速度非常快,因为它们不需要重新排列其他元素。 -
处理固定数量的数据 - 如果事先知道要存储多少个元素,数组的工作效率会特别高。数组可以一次性分配内存,从而将调整大小的开销降至最低。
-
矢量计算和线性代数 - Julia 优化了数组,尤其是数值数组的处理。如果要处理矩阵、向量或执行线性代数运算,数组是最佳选择。例如,处理矩阵的函数(如
dot
、cross
)或通过broadcast 进行的数组运算(.+
、.*
)在数组中运行速度更快。
不推荐使用数组时
-
频繁添加或删除中间或开头的元素 - 如果需要频繁插入或删除数组开头或中间的元素。例如,"insert!"(插入)和 "deleteat!"(删除)函数需要移动所有后续元素,因此对于大型数组来说效率很低。替代方法:使用
DataStructures.jl
包中的Deque
函数,它对两端的插入和删除进行了优化。 -
按键查找项目 - 如果需要按唯一键(如用户名或 ID)快速查找项目,则不适合使用数组,因为数组是通过搜索所有项目来查找的(这相当耗时)。替代方法:使用
Dict
(字典),它可以让你按键快速查找项目。 -
频繁调整结构大小--如果数据结构频繁变化(例如,在任意位置添加或删除元素),数组就会失效。替代方法:考虑使用link:https://juliacollections.github.io/DataStructures.jl/latest/ 包 [DataStructures.jl] 中的
Set
、Dict
或列表结构(如List
)。 -
使用不可变数据 - Julia 中的数组是可变的,这意味着它们的元素在创建后可以更改。如果需要不可变的数据结构,最好使用元组(Tuple)。元组不允许更改元素,因此便于存储恒定数据。例如
t = (1, 2, 3) t[1] = 10 # Ошибка! Кортежи неизменяемы
字符串和符号的数组、矩阵和向量
在 Julia 中,数组、矩阵和向量可以像数字一样包含字符串或符号。
# Вектор строк
v = ["apple", "banana", "cherry"]
println(v[1]) # apple
# Матрица символов
m = ['a' 'b'; 'c' 'd']
println(m[1, 2]) # b
# Трехмерный массив строк
a = [["a", "b"], ["c", "d"]]
println(a[1][2]) # "b"
-
字符串向量—每个字符串都作为一维数组的一个元素存储。
-
字符矩阵 - 一个二维数组,每个元素都是一个字符。
-
字符串三维数组 - 支持文本数据的任意维数。
Julia 中的数组默认为动态数组,但其长度是固定的,除非明确更改。这意味着创建数组时,其当前长度保持不变,直到使用了 "push!"、"append!"或 "resize!"等特殊方法。这样做是为了提高性能:固定长度的操作不需要不断重新分配内存,因此速度更快。
带有 end
的更复杂的结构(如 end+1
)不允许直接为数组元素赋值,因为此类操作超出了当前长度。要添加新元素,必须明确地增加数组的大小。例如,可以使用 resize!
:
a = [10, 20, 30]
resize!(a, length(a) + 1) # Расширяем массив на 1 элемент
a[end] = 40 # Присваиваем значение новому элементу
println(a) # [10, 20, 30, 40]
带有 end
的构造可用于对现有数组边界内的索引进行索引和算术运算。例如
-
a[end]
- 访问最后一个元素。 -
a[end-1]
- 访问从末尾开始的第二个元素。 -
a[1:end]
- 访问整个数组。 -
a[1:end-1]
- 获取除最后一个元素以外的所有元素。
在 Julia 中,不能直接为索引为 end+1 的元素赋值,也不能为超出数组当前长度的任何索引赋值。要调整数组的大小,必须使用特殊的方法,如`resize!、`push!`或`append! 。
|
数组索引
Julia 中的索引从 1 开始,即数组的第一个元素的索引为 1
。数组还支持特殊的 "end "索引,表示数组的最后一个元素或相应维度的大小。索引示例
a = [10, 20, 30, 40]
println(a[1]) # 10 — первый элемент
println(a[end]) # 40 — последний элемент
# Индексация матриц
m = [1 2; 3 4]
println(m[1, end]) # 2 — последний элемент первой строки
-
索引
1
总是指向第一个元素。 -
end "用于指一维和多维数组中的最后一个元素。
-
对于矩阵,第一个索引是行号,第二个索引是列号。
*其他索引变化:
-
使用范围可以同时引用数组中的多个元素:
b = [1, 2, 3, 4, 5] println(b[2:end]) # [2, 3, 4, 5] — элементы со второго до последнего
-
以特定增量选择元素:
b = [1, 2, 3, 4, 5] println(b[1:2:end]) # [1, 3, 5] — элементы с шагом 2
在 Julia 中,"1:2:end "形式的表达式称为范围。范围是一种结构,它描述了一个有起点、级数和终点的数字序列。例如,
1:2:5`创建了一个以 2 为增量从 1 到 5 的序列:
[1, 3, 5]`。在这个例子中,
1:2:end
表示选择从数组的第一个元素(1
)开始,以增量`2`进行,并以数组的最后一个元素(end
)结束。使用范围可以方便有效地处理数组和矩阵索引。使用范围的示例# Простые диапазоны r1 = 1:5 # Создает последовательность [1, 2, 3, 4, 5] r2 = 1:2:10 # Создает последовательность [1, 3, 5, 7, 9] # Использование диапазона для индексации a = [10, 20, 30, 40, 50] println(a[2:4]) # [20, 30, 40] println(a[1:2:end]) # [10, 30, 50] # Диапазон с "end" println(a[3:end]) # [30, 40, 50]
-
选择符合特定条件的项目(详见章节)。 逻辑索引):
b = [1, 2, 3, 4, 5] println(b[b .> 3]) # [4, 5] — элементы больше 3
在 Julia 中,不仅可以直接设置范围,还可以使用变量来设置范围。例如
arr = [10, 20, 30, 40, 50]
a = 1:2:5 # Задаем диапазон в переменной
println(arr[a]) # [10, 30, 50]
逻辑索引
Julia 中的逻辑索引允许您根据返回与原始数组维度相同的逻辑数组(true
/false
)的条件来选择数组元素。这种方法对于过滤数据非常有用。
+ 示例
# Исходный массив
a = [10, 20, 30, 40, 50]
# Условие: выбрать элементы больше 25
filtered = a[a .> 25] # [30, 40, 50]
println(filtered)
# Условие: элементы, которые кратны 10
filtered = a[a .% 10 .== 0] # [10, 20, 30, 40, 50]
println(filtered)
这里
-
条件前的
.
运算符(.>
,.==
)表示分段运算。关于此类运算的更详细说明,请参阅矢量化和逻辑索引 一文。 -
逻辑数组 `[false,false,true,true,true]`将用于选择相应的元素。
多维数组示例:
# Матрица 2x3
m = [1 2 3; 4 5 6]
# Условие: выбрать элементы больше 3
filtered = m[m .> 3] # [4, 5, 6]
println(filtered)
处理数组、向量和矩阵的操作符
Julia 提供的操作符可以简化数组的处理,无论是一维数组(矢量)、二维数组(矩阵)还是更复杂的多维数组结构。以下是用于索引、转换和组合数据的主要操作符:
-
操作符
:
用于沿特定维度选择数组的所有元素或创建范围。例如
# Исходный массив m = [1 2 3; 4 5 6; 7 8 9] # Все элементы первой строки println(m[1, :]) # [1, 2, 3] # Все элементы второго столбца println(m[:, 2]) # [2, 5, 8] # Диапазон индексов println(m[1:2, 1:2]) # [1 2; 4 5]
-
''''运算符用于连接 (实数的转置)。它只适用于数字数组。
例如
# Вектор-строка v = [1 2 3] # Транспонирование в столбец println(v') # [1; 2; 3;;]
要使用复数对数组进行换置, '
运算符也会返回复数共轭结果。如果只需要行到列的转置(不需要共轭),请使用transpose
函数。
要对包含非数字元素(如字符串或用户定义类型)的数组进行换置,请使用 如果将
|
-
操作符
;
用于纵向组合数组,即添加行。例如
# Исходные 向量ы a = [1, 2, 3] b = [4, 5, 6] # Вертикальная конкатенация result = [a; b] println(result) # 6-element Vector{Int64}:[1; 2; 3; 4; 5; 6]
使用 for
对数组进行遍历
在 Julia 中,使用 for
循环可以方便地遍历数组。让我们来看看通过 for
处理数组的基本方法。以下语法用于循环遍历数组中的所有元素:
arr = [10, 20, 30, 40]
for x in arr
println(x)
end
输出
10
20
30
40
有时不仅需要获取值,还需要获取它们的索引。为此,可以使用 eachindex
自动选择最佳索引方法:
arr = ["a", "b", "c"]
for i in eachindex(arr)
println("Элемент ", i, ": ", arr[i])
end
输出
Элемент 1: a
Элемент 2: b
Элемент 3: c
另一种获取索引和值的方法是使用`enumerate`函数:
arr = ["apple", "banana", "cherry"]
for (i, val) in enumerate(arr)
println("$i: $val")
end
输出
1: apple
2: banana
3: cherry
对于多维数组,可以使用嵌套循环:
matrix = [1 2 3; 4 5 6]
for i in 1:size(matrix, 1) # Проход по строкам
for j in 1:size(matrix, 2) # Проход по столбцам
println("matrix[$i, $j] = ", matrix[i, j])
end
end
输出
matrix[1, 1] = 1
matrix[1, 2] = 2
matrix[1, 3] = 3
matrix[2, 1] = 4
matrix[2, 2] = 5
matrix[2, 3] = 6
您可以直接使用 for
代替嵌套循环:
matrix = [1 2 3; 4 5 6]
for x in matrix
println(x)
end
输出
1
4
2
5
3
6
Julia 按列而不是按行遍历元素。要按行绕过数组,可以使用`permutedims`或`eachrow`:
for row in eachrow(matrix)
println(row)
end
输出
[1, 2, 3]
[4, 5, 6]