索引表达式允许您引用或提取向量、矩阵(二维)或更高维数组中的选定元素。数组可以通过以下三种方式之一进行索引:分量索引、线性索引和逻辑索引。
分量索引可以是标量、向量、范围或特殊运算符:,后者选择整个行、列或更高维度的切片。
分量索引表达式由一组括号构成,括号内包含用逗号分隔的 M 个表达式。每个单独的索引值(即分量)用于其所应用对象的相应维度。换句话说,第一个索引分量用于对象的第一个维度(行),第二个索引分量用于对象的第二个维度(列),依此类推。索引分量的数量 M 定义了索引表达式的维度。具有两个分量的索引被称为二维索引,因为它有两个维度。
在最简单的情况下,1)所有分量都是标量,2)索引表达式的维度 M 等于其所应用对象的维度。例如:
A = reshape (1:8, 2, 2, 2) # 创建三维数组
A =
ans(:,:,1) =
1 3
2 4
ans(:,:,2) =
5 7
6 8
A(2, 1, 2) # 第二个切片的第二行、第一列
# 在第三维中:ans = 6
返回对象在特定维度上的大小等于索引表达式对应分量中元素的数量。当所有分量都是标量时,结果是一个单一的输出值。然而,如果任何分量是向量或范围,则返回的值是各个维度中索引的笛卡尔积。例如:
A([1, 2], 1, 2) ≡ [A(1,1,2); A(2,1,2)] ⇒ ans = 5 6
返回值的总数是每个索引分量返回的元素数的乘积。在上面的例子中,总数是 2 * 1 * 1 = 2 个元素。
请注意,给定维度中返回对象的大小等于该维度索引表达式中的元素数。在上面的代码中,第一个索引分量([1, 2])被指定为行向量,但其形状并不重要。重要的事实是,该分量指定了两个值,因此结果在第一维度上的大小必须为 2;而由于第一维度对应行,所以整体结果是一个列向量。
A(1, [2, 1, 1], 1) # 结果是行向量:ans = [3, 1, 1] A(ones (2, 2), 1, 1) # 结果是列向量:ans = [1; 1; 1; 1]
第一行再次说明了输出在给定维度上的大小等于相应索引分量中元素的数量。在这种情况下,输出在第二维度(对应列)上有三个元素,因此结果是行向量。该示例还展示了如何使用索引表达式中的重复分量来在输出中复制元素。最后一个例子进一步证明了索引分量的形状是无关紧要的,重要的只是元素的数量(2×2 = 4)。
上述规则适用于索引表达式的维度大于 1(M > 1)的情况。然而,对于一维索引表达式,则适用特殊规则,输出的形状确实由索引分量的形状决定。例如:
A([1, 2]) # 结果是行向量:ans = [1, 2] A([1; 2]) # 结果是列向量:ans = [1; 2]
A(P) 的形状规则如下:
冒号(:)可以用作索引分量,以选择指定维度中的所有元素。给定矩阵:
A = [1, 2; 3, 4]
以下所有表达式都是等价的,都用于选择矩阵的第一行。
A(1, [1, 2]) # 第1行,第1列和第2列 A(1, 1:2) # 第1行,范围1-2内的列 A(1, :) # 第1行,所有列
在特殊的一维索引情况下使用冒号时,结果总是列向量。使用冒号索引创建列向量是一种非常常见的代码惯用法,在这种情况下比调用 reshape 更快且通常更清晰。
A(:) # 结果是列向量:ans = [1; 2; 3; 4] A(:)' # 结果是行向量:ans = [1, 2, 3, 4]
在索引表达式中,关键字 end 自动引用特定维度的最后一个条目。这个魔法索引也可以在范围中使用,通常无需在索引前调用 size 或 length 来获取数组边界。例如:
A(1:end/2) # A 的前半部分 => [1, 2] A(end + 1) = 5; # 追加元素 A(end) = []; # 删除元素 A(1:2:end) # A 的奇数位置元素 => [1, 3] A(2:2:end) # A 的偶数位置元素 => [2, 4] A(end:-1:1) # A 的逆序 => [4, 3, 2, 1]
有关更多信息,请参见"end" 关键字。
允许对多维对象使用一维索引。这也称为线性索引。在这种情况下,多维数组的元素按照 Fortran 中的列优先顺序获取。也就是说,数组的列被想象成堆叠在一起形成一个列向量,然后将单一的线性索引应用于该向量。
A = [1, 2, 3; 4, 5, 6; 7, 8, 9]; A(4) # 二维数组中第4个元素的线性索引:ans = 2 A(3:5) # 结果具有索引分量的形状:ans = [7, 2, 5] A([1, 2, 2, 1]) # 结果包含重复元素:ans = [1, 4, 4, 1]
逻辑值也可以用于索引矩阵和元胞数组。当使用逻辑数组进行索引时,结果将是一个向量,其中包含逻辑数组中 true 位置对应的值。以下示例说明了这一点。
data = [ 1, 2; 3, 4 ];
idx = [true, false; false true];
data(idx)
⇒ ans = [ 1; 4 ]
idx = (data <= 2);
data(idx)
⇒ ans = [ 1; 2 ]
除了创建 idx 数组之外,也可以将上述代码中的 data(idx) 替换为 data( data <= 2 )。
虽然逻辑索引表达式的大小通常与被索引数组的大小相同,但这不是必要条件。如果逻辑索引的大小与数组不同,那么数组中的元素将根据其线性顺序与逻辑索引中的元素进行匹配,就像线性索引那样。
data = [ 1, 2, 3; 4, 5, 6 ];
idx = [ true, false, false, true ];
data(idx)
⇒ ans = [ 1 5 ] # idx 选择了第1和第4位置的元素
如果逻辑索引大于数组,且任何 true 值试图选择超出数组中元素总数的线性位置时,将发生越界错误。
idx = [ true, true, false; false, true, false; true; false; false ];
data(idx)
⇒ ans = [ 1; 2; 5; 3 ] # 返回列中的第1、3、4、5位置
idx = [ true, true, false; false, true, false; true; false; true ];
data(idx)
⇒ error: a(9): out of bound 6 (dimensions are 2x3)
逻辑索引中超出数组大小的 false 元素会被忽略,但当逻辑索引的第九个元素为 true 时,它会试图选择数组中不存在的第九个元素,从而触发错误。
版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-4