【问题标题】:Linear indexing, logical indexing, and all that线性索引、逻辑索引等等
【发布时间】:2015-11-29 12:50:13
【问题描述】:

我们习惯了 Matlab 中不同形式的索引:

  • 标准(在每个维度上使用整数),
  • 逻辑(使用逻辑值),
  • 线性(使用单个索引遍历多维数组)。

乍一看,这些形式似乎是互斥的:索引要么是标准的,要么是逻辑的,要么是线性的。然而,有时这些形式中的几种似乎是混合的。例如,

>> A = magic(3)
A =
     8     1     6
     3     5     7
     4     9     2
>> A(A>5)
ans =
     8
     9
     6
     7

这是逻辑索引,对吗?但它也有一些线性索引的特点,因为返回的是一个列向量。其实逻辑索引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

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

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

  • Matlab 中有哪些类型的索引?
  • 如何组合?
  • 应该如何称呼他们?

【问题讨论】:

    标签: arrays matlab matrix matrix-indexing


    【解决方案1】:

    在下文中,我使用了我认为或多或少符合标准 Matlab 实践的术语。然而,在某些情况下,我不得不编一个名字,因为我不知道现有的名字。如果有比我使用的更多的标准名称,请告诉我。

    此答案试图阐明不同类型的索引以及如何组合它们。另一个问题是如何将输出数组的 shape (size) 确定为索引变量形状的函数。 Loren Shure 的 Essence of indexing 是一个很好的帖子。

    下面的描述主要是数值数组的索引,但它可以应用于单元数组,无论是括号还是花括号索引,都有明显的变化输出类型(分别为元胞数组或逗号分隔列表)。这将在最后简要讨论。

    数值数组中的索引类型

    索引可以根据以下两个属性进行分类。

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

      • 多维索引为数组的每个维度指定一个索引变量。在 Matlab 文档中,各个索引有时称为 下标(参见例如 sub2ind)。
      • 线性索引指定一个索引变量,该变量在所有维度上遍历数组(这可以看作是所有维度合并为一个)。我们知道,遍历首先是沿列,然后是沿行,然后是沿第三维切片等(所谓的column-major order)。
      • 部分线性索引:给定一个具有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
    
    1. 多维整数值:

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

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

      >> A([1 2], 2:4)
      ans =
           1     6    17
           5     7    12
      
    4. 多维、逻辑:

      >> 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 Mathworksthis answer by Jonas

    5. 线性,逻辑:

      >> A([false true false false true true true])
      ans =
           3     5     9     6
      

      (请注意,11 个尾随 false 值已被遗漏在索引向量中。)

    6. 部分线性,逻辑:

      >> A([true true false], [false true true true false false])
      ans =
           1     6    17
           5     7    12
      

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

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

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

      >> 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

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

    【讨论】:

    • 我首先认为它会与this Q/A 重复。它不是,但无论如何它是高度相关的。我会包含这个答案,因为它解释了与错误索引相关的所有错误。
    • @thewaywewalk 我看不出这个问答有多大关系,是吗?那一个处理错误导致索引具有不正确的值或通过变量名隐藏函数。这个是关于存在的不同类型的索引,根据两个标准;并试图强调这两个标准是独立的
    • 昨天发现了一些有趣的东西,简化版:x=rand(1,10);y=x(magic(3))。使用 3x3 线性线性整数索引来索引向量,最终得到一个 3x3 矩阵。
    • @Daniel 是的,关于输出的形状,我在答案中链接的this post 非常全面
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多