以下内容中我使用了与标准Matlab实践更或多或少一致的
术语。但在某些情况下,我不得不杜撰一个名称,因为我不知道现有的名称。如果有比我使用的更标准的名称,请告诉我。
本答案旨在澄清不同类型的索引以及如何组合它们。另一个问题是根据索引变量的形状确定输出数组的
形状(
size
)函数。Loren Shure在
Essence of indexing中发表了一篇好文章。
以下描述重点讨论了
数字数组的索引,但可以应用于使用括号或花括号索引的
单元格数组,相应地改变输出类型(单元格数组或逗号分隔列表),这将在最后简要讨论。
数字数组的索引类型
考虑以下两个属性,可以对索引进行分类。
根据每个索引变量所涉及的维度数量,索引可以是多维的或线性的。但这只是两种极端情况。存在一种中间情况,可能被称为部分线性索引:
- 纯多维 索引为数组的每个维度指定一个索引变量。 Matlab 文档有时将这些单独的索引称为 下标 (例如查看
sub2ind
)。
- 纯线性 索引指定一个单一的索引变量,它跨越所有维度遍历数组(可以视为所有维度都折叠成一个)。正如我们所知道的,遍历首先沿列进行,然后沿行进行,然后沿第三个维度片遍历等(所谓的列主序)。
- 部分线性 索引:给定一个具有
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
Multidimensional, integer-valued:
>> A([1 2], 2, 2)
ans =
10
14
Linear, integer-valued:
>> A([2 5:7])
ans =
3 5 9 6
Partially linear, integer-valued:
>> A([1 2], 2:4)
ans =
1 6 17
5 7 12
Multidimensional, logical:
>> A([true true false], [false true false], [false true])
ans =
10
14
Interestingly, the number of logical values may be smaller, or even larger, than the size in the dimension the index refers to:
>> A([true true], [false true false false], [false true])
ans =
10
14
Missing values are interpreted as false
, and surplus values must be false
or an error will occur. See for example this page by Mathworks or this answer by Jonas.
Linear, logical:
>> A([false true false false true true true])
ans =
3 5 9 6
(Note that 11 trailing false
values have been left out in the indexing vector.)
Partially linear, logical:
>> A([true true false], [false true true true false false])
ans =
1 6 17
5 7 12
在多维或部分线性索引中,存在多个索引变量,每个变量可以独立地是整数或逻辑类型。这会产生不同的混合类型。例如:
Multidimensional, logical/integer-valued:
>> A([true false true], [false true true], 2)
ans =
10 15
18 11
Partially linear, integer-valued/logical:
>> 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
逻辑索引和线性索引并不是互斥的索引类型,它们是独立的索引特征。"逻辑"指的是索引值的类型,而"线性"表示多个维度被合并为一个进行索引。这两种特征可以同时发生。
x=rand(1,10);y=x(magic(3))
。使用一个3x3的线性整数索引来索引一个向量,最终得到一个3x3的矩阵。 - Daniel