在下文中,我使用了我认为或多或少符合标准 Matlab 实践的术语。然而,在某些情况下,我不得不编一个名字,因为我不知道现有的名字。如果有比我使用的更多的标准名称,请告诉我。
此答案试图阐明不同类型的索引以及如何组合它们。另一个问题是如何将输出数组的 shape (size) 确定为索引变量形状的函数。 Loren Shure 的 Essence of indexing 是一个很好的帖子。
下面的描述主要是数值数组的索引,但它可以应用于单元数组,无论是括号还是花括号索引,都有明显的变化输出类型(分别为元胞数组或逗号分隔列表)。这将在最后简要讨论。
数值数组中的索引类型
索引可以根据以下两个属性进行分类。
-
根据每个索引变量所指的维数,索引可以是多维的,也可以是线性的。但这只是两种极端情况。存在一种中间情况,可以称为部分线性索引:
- 纯多维索引为数组的每个维度指定一个索引变量。在 Matlab 文档中,各个索引有时称为 下标(参见例如
sub2ind)。
- 纯线性索引指定一个索引变量,该变量在所有维度上遍历数组(这可以看作是所有维度合并为一个)。我们知道,遍历首先是沿列,然后是沿行,然后是沿第三维切片等(所谓的column-major order)。
-
部分线性索引:给定一个具有
m+n 维度的数组n>=2,可以为第一个m 维度指定m 索引变量(因此在这些维度中使用多维索引)和一个最后一个n 维度的索引变量,它仅被解释为这些维度的线性索引(最后一个n 维度合并为一个)。
-
根据索引值的类型,每个索引变量可以是整数值或逻辑值:
- 如果索引变量包含正整数,则为整数值;
- 如果索引变量包含逻辑值,则为逻辑。
分类标准 1 和 2 是独立的。从标准 1 的角度来看,索引的类别与其根据标准 2 的类别没有关系。所有组合都是可能的。
因此,根据上述分类,有6种基本类型的索引。为了澄清,以下是每个示例。所有示例都使用数组A = cat(3, magic(3), 9+magic(3)),即
A(:,:,1) =
8 1 6
3 5 7
4 9 2
A(:,:,2) =
17 10 15
12 14 16
13 18 11
-
多维整数值:
>> A([1 2], 2, 2)
ans =
10
14
-
线性,整数值:
>> A([2 5:7])
ans =
3 5 9 6
-
部分线性,整数值:
>> A([1 2], 2:4)
ans =
1 6 17
5 7 12
-
多维、逻辑:
>> A([true true false], [false true false], [false true])
ans =
10
14
有趣的是,逻辑值的数量可能小于,甚至大于索引所指维度中的大小:
>> A([true true], [false true false false], [false true])
ans =
10
14
缺失值解释为false,剩余值必须为false,否则会出错。参见例如this page by Mathworks 或this answer by Jonas。
-
线性,逻辑:
>> A([false true false false true true true])
ans =
3 5 9 6
(请注意,11 个尾随 false 值已被遗漏在索引向量中。)
-
部分线性,逻辑:
>> A([true true false], [false true true true false false])
ans =
1 6 17
5 7 12
在多维或部分线性索引中,其中有多个索引变量,每个索引变量都可以独立地是整数值或逻辑值。这就产生了不同的混合类型。例如:
-
多维、逻辑/整数值:
>> A([true false true], [false true true], 2)
ans =
10 15
18 11
-
部分线性、整数值/逻辑:
>> A([1 2], [true false true false true false])
ans =
8 6 10
3 7 14
如果被索引的数组是稀疏矩阵,上述所有内容仍然适用,除了矩阵不存在部分线性索引;当然结果也是稀疏的。
元胞数组的索引
为数值数组描述的所有索引类型都可以应用于元胞数组,但需要额外考虑。元胞数组可以用括号或花括号来索引。在第一种情况下,索引的结果是一个元胞数组。第二个是单元格内容的逗号分隔列表。
举个例子,假设前面例子中使用的数值数组转化为元胞数组C = num2cell(A),即
C(:,:,1) =
[8] [1] [6]
[3] [5] [7]
[4] [9] [2]
C(:,:,2) =
[17] [10] [15]
[12] [14] [16]
[13] [18] [11]
那么上面示例 8 中使用的索引将产生元胞数组
>> C([1 2], [true false true false true false])
ans =
[8] [6] [10]
[3] [7] [14]
而使用花括号会产生逗号分隔的列表
>> C{[1 2], [true false true false true false]}
ans =
8
ans =
3
ans =
6
ans =
7
ans =
10
ans =
14
外卖消息/TL;DR
逻辑和线性索引不是唯一的索引类型。相反,它们是索引的两个独立特征。 “逻辑”是指索引值的类型,“线性”表示多个维度被折叠并索引为一个。这两个功能可以同时发生。