线性索引,逻辑索引以及所有这些

Lui*_*ndo 33 arrays matlab matrix matrix-indexing

我们习惯于在Matlab中使用不同形式的索引:

  • 标准(使用每个维度的整数),
  • 逻辑(使用逻辑值),
  • 线性(使用单个索引遍历具有多个维度的数组).

乍一看,似乎这些形式是独占的:索引是标准的,逻辑的或线性的.然而,有时似乎在这些形式中的几种之间存在混合.例如,

>> A = magic(3)
A =
     8     1     6
     3     5     7
     4     9     2
>> A(A>5)
ans =
     8
     9
     6
     7
Run Code Online (Sandbox Code Playgroud)

这是合乎逻辑的索引,对吧?但它也具有线性索引的一些功能,因为返回了列向量.实际上,逻辑索引A>5与线性索引具有相同的效果find(A>5).

作为第二个例子,考虑一下

>> A = magic(3)
A =
     8     1     6
     3     5     7
     4     9     2
>> A(1:2, [true false true])
ans =
     8     6
     3     7
Run Code Online (Sandbox Code Playgroud)

在此表达式中,标准(整数值)索引用于第一个坐标,逻辑索引用于第二个坐标.

这些例子(以及在实践中出现的更复杂的例子)提出了以下问题:

  • Matlab有哪些类型的索引?
  • 它们如何结合起来?
  • 他们应该如何被提及?

Lui*_*ndo 38

在下面我使用的术语我认为或多或少符合标准的Matlab实践.但是,在某些情况下,我不得不排序 - 因为我不知道现有的名字.如果有比我正在使用的标准名称更多的标准名称,请告诉我.

这个答案试图澄清不同类型的索引以及它们如何组合.另一个问题是输出数组的shape(size)如何确定为索引变量形状的函数.关于这一点的好帖子是Loren Shure 的索引精华.

下面的描述着重于索引数值阵列,但它可以应用到单元阵列与任一括号或大括号索引,与输出型(单元阵列或逗号分隔的列表,分别地)的明显变化.这将在最后简要讨论.

数值数组中的索引类型

可以考虑以下两个属性对索引进行分类.

  1. 根据每个索引变量所指的维数,索引可以是多维的或线性的.但这些只是两种极端情况.存在中间情况,可称为部分线性索引:

    • 多维索引为数组的每个维度指定索引变量.各个索引有时在Matlab文档中称为下标(例如,参见参考资料sub2ind).
    • 线性索引指定一个索引变量,该变量遍历所有维度的数组(这可以看作是所有维度都折叠成一个).我们知道,遍历首先是沿着列,然后沿着行,然后沿着第三个暗淡的切片等(所谓的列主要顺序).
    • 部分线性索引:给定具有m+n维度的数组n>=2,可以指定m第一m维的索引变量(因此在这些维度中使用多维索引)和最后n维度的一个索引变量,这些变量仅被解释为这些维度的线性索引(最后的n维度合并为一个).
  2. 根据索引值的类型,每个索引变量可以是整数值或逻辑:

    • 如果索引变量包含正整数,则它是整数值 ;
    • 如果索引变量包含逻辑值,则这是合乎逻辑的.

分类标准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
Run Code Online (Sandbox Code Playgroud)
  1. 多维,整数值:

    >> A([1 2], 2, 2)
    ans =
        10
        14
    
    Run Code Online (Sandbox Code Playgroud)
  2. 线性,整数值:

    >> A([2 5:7])
    ans =
         3     5     9     6
    
    Run Code Online (Sandbox Code Playgroud)
  3. 部分线性,整数值:

    >> A([1 2], 2:4)
    ans =
         1     6    17
         5     7    12
    
    Run Code Online (Sandbox Code Playgroud)
  4. 多维,合乎逻辑:

    >> A([true true false], [false true false], [false true])
    ans =
        10
        14
    
    Run Code Online (Sandbox Code Playgroud)

    有趣的是,逻辑值的数量可能比索引所指的维度中的大小更小,甚至更大:

    >> A([true true], [false true false false], [false true])
    ans =
        10
        14
    
    Run Code Online (Sandbox Code Playgroud)

    缺失值被解释为false,并且必须是剩余值false或将发生错误.请参阅Mathworks的此页面Jonas的回答.

  5. 线性,逻辑:

    >> A([false true false false true true true])
    ans =
         3     5     9     6
    
    Run Code Online (Sandbox Code Playgroud)

    (请注意,false索引向量中省略了11个尾随值.)

  6. 部分线性,合乎逻辑:

    >> A([true true false], [false true true true false false])
    ans =
         1     6    17
         5     7    12
    
    Run Code Online (Sandbox Code Playgroud)

在多维或部分线性索引中,其中存在多个索引变量,每个索引变量可以独立地为整数值或逻辑.这产生了不同的混合类型.例如:

  1. 多维,逻辑/整数值:

    >> A([true false true], [false true true], 2)
    ans =
        10    15
        18    11
    
    Run Code Online (Sandbox Code Playgroud)
  2. 部分线性,整数值/逻辑:

    >> A([1 2], [true false true false true false])
    ans =
         8     6    10
         3     7    14
    
    Run Code Online (Sandbox Code Playgroud)

如果被索引的数组是稀疏矩阵,则上述所有内容仍然适用,除了矩阵不存在部分线性索引; 当然结果也很稀疏.

索引单元阵列

可以将针对数值阵列描述的所有类型的索引应用于单元阵列,还有一个额外的考虑因素.单元格数组可以用括号或花括号索引.在第一种情况下,索引的结果是单元阵列.在第二个中,它是以逗号分隔的单元格内容列表.

作为一个例子,假设前面例子中使用的数值数组被转换成单元格数组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]
Run Code Online (Sandbox Code Playgroud)

然后,上面的示例8中使用的索引将产生单元阵列

>> C([1 2], [true false true false true false])
ans = 
    [8]    [6]    [10]
    [3]    [7]    [14]
Run Code Online (Sandbox Code Playgroud)

而使用花括号会产生以逗号分隔的列表

>> C{[1 2], [true false true false true false]}
ans =
     8
ans =
     3
ans =
     6
ans =
     7
ans =
    10
ans =
    14 
Run Code Online (Sandbox Code Playgroud)

外卖消息/ TL; DR

逻辑和线性索引不是索引的唯一类型.相反,它们是索引的两个独立功能."逻辑"是指索引值的类型,"线性"表示多个维度正在折叠并索引为一个维度.这两个功能可以同时发生.