线性索引、逻辑索引等等

发布于 2025-01-16 12:23:47 字数 865 浏览 0 评论 0原文

我们习惯了 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 中有哪些类型的索引?
  • 如何组合它们?
  • 如何组合他们应该被提及吗?

We are used to different forms of indexing in Matlab:

  • standard (using integers along each dimension),
  • logical (using logical values),
  • linear (using a single index to traverse an array with more than one dimension).

At first sight, it may appear that these forms are exclusive: an index is either standard, or logical, or linear. However, sometimes there appears to be a blend between several of these forms. For example,

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

This is logical indexing, right? But it also has some features of linear indexing, because a column vector is returned. In fact, the logical index A>5 has the same effect as the linear index find(A>5).

As a second example, consider

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

In this expression, standard (integer-valued) indexing is used for the first coordinate, and logical indexing is used for the second.

These examples (and more complicated ones that arise in practice) pose the following questions:

  • What types of indexing are there in Matlab?
  • How can they be combined?
  • How should they be referred to?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫性小仙女 2025-01-23 12:23:47

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

这个答案试图阐明不同类型的索引以及如何组合它们。另一个问题是如何将输出数组的形状大小)确定为索引变量形状的函数。 索引的本质,作者:洛伦·舒尔。

接下来的描述重点关注数字数组的索引,但它可以应用于带有括号或大括号索引的元胞数组,输出类型有明显的变化(分别为元胞数组或逗号分隔列表)。这将在最后简要讨论。

数值数组中的索引类型

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

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

    • 多维索引为数组的每个维度指定一个索引变量。在 Matlab 文档中,各个索引有时被称为下标(例如,请参见 sub2ind)。
    • 线性索引指定一个索引变量,该变量跨所有维度遍历数组(这可以视为所有维度都合并为一个)。众所周知,遍历首先沿着列,然后沿着行,然后沿着第三维切片,等等(所谓的 列主顺序)。
    • 部分线性索引:给定一个具有 m+n 维度的数组,n>=2,可以指定 m< /code> 前 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)
    答案=
    10
    14

  2. 线性,整数值:

    <前><代码>>> A([2 5:7])
    答案=
    3 5 9 6

  3. 部分线性,整数值:

    <前><代码>>> A([1 2], 2:4)
    答案=
    1 6 17
    5 7 12

  4. 多维,逻辑:

    <前><代码>>> A([真真假],[假真假],[假真])
    答案=
    10
    14

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

    <前><代码>>> A([真真],[假真假假],[假真])
    答案=
    10
    14

    缺失值被解释为false,剩余值必须为false,否则会出现错误。例如,请参阅 Mathworks 的此页面Jonas 的回答

  5. 线性、逻辑:

    <前><代码>>> A([假真假假假真真真])
    答案=
    3 5 9 6

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

  6. 部分线性,逻辑:

    <前><代码>>> A([真真假],[假真真真假假])
    答案=
    1 6 17
    5 7 12

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

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

    <前><代码>>> A([真假真],[假真真], 2)
    答案=
    10 15
    18 11

  2. 部分线性、整数值/逻辑:

    <前><代码>>> A([1 2],[真假真假真假])
    答案=
    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

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

In the following I use terminology that I think is more or less in line with standard Matlab practice. However, in some cases I've had to sort-of make up a name because I wasn't aware of an existing one. Please let me know if there are more standard names than those I'm using.

This answer tries to clarify the different types of indexing and how they can be combined. A different question is how the shape (size) of the output array is determined as a function of the shape of the index variables. A good post on this is Essence of indexing by Loren Shure.

The description to follow focuses on indexing of numerical arrays, but it can be applied to cell arrays with either parenthesis or curly-brace indexing, with the obvious change of output type (cell array or comma-separated list, respectively). This will be briefly discussed at the end.

Types of indexing in numerical arrays

Indexing can be classified considering the following two attributes.

  1. According to the number of dimensions each index variable refers to, indexing can be multidimensional or linear. But these are only two extreme cases. An intermediate situation exists, which may be termed partially linear indexing:

    • Pure multidimensional indexing specifies an index variable for each dimension of the array. The individual indices are sometimes referred to as subscripts in Matlab documentation (see for example sub2ind).
    • Pure linear indexing specifies a single index variable that traverses the array across all dimensions (this can be viewed as if all dimensions collapse into one). As we know, the traversal is along columns first, then along rows, then along third-dim slices, etc (so-called column-major order).
    • Partially linear indexing: given an array with m+n dimensions, n>=2, one can specify m index variables for the first m dimensions (thus using multidimensional indexing in those dimensions) and one index variable for the last n dimensions, which is interpreted as a linear index for those dimensions only (the last n dimensions collapse into one).
  2. Acccording to the type of the index values, each index variable can be integer-valued or logical:

    • It is integer-valued if the index variable contains positive integers;
    • It is logical if the index variable contains logical values.

Classification criteria 1 and 2 are independent. The category of the index from the point of view of criterion 1 has no relationship with its category according to criterion 2. All combinations are possible.

Thus, according to the above classification, there are 6 basic types of indexing. To clarify, following is an example for each. All examples use the array A = cat(3, magic(3), 9+magic(3)), that is,

A(:,:,1) =
     8     1     6
     3     5     7
     4     9     2
A(:,:,2) =
    17    10    15
    12    14    16
    13    18    11
  1. Multidimensional, integer-valued:

    >> A([1 2], 2, 2)
    ans =
        10
        14
    
  2. Linear, integer-valued:

    >> A([2 5:7])
    ans =
         3     5     9     6
    
  3. Partially linear, integer-valued:

    >> A([1 2], 2:4)
    ans =
         1     6    17
         5     7    12
    
  4. 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.

  5. 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.)

  6. Partially linear, logical:

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

In multidimensional or partially linear indexing, in which there is more than one index variable, each can independently be integer-valued or logical. This gives rise to different mixed types. For example:

  1. Multidimensional, logical/integer-valued:

    >> A([true false true], [false true true], 2)
    ans =
        10    15
        18    11
    
  2. Partially linear, integer-valued/logical:

    >> A([1 2], [true false true false true false])
    ans =
         8     6    10
         3     7    14
    

If the array that is being indexed is a sparse matrix all of the above still applies, except that partially linear indexing doesn't exist for matrices; and of course the result is also sparse.

Indexing of cell arrays

All the types of indexing described for numerical arrays can be applied to cell arrays, with one additional consideration. Cell arrays can be indexed with parentheses or with curly braces. In the first case the result of the indexing is a cell array. In the second it is a comma-separated list of the cell contents.

As an example, suppose the numerical array used in the previous examples is transformed into the cell array C = num2cell(A), that is,

C(:,:,1) = 
    [8]    [1]    [6]
    [3]    [5]    [7]
    [4]    [9]    [2]
C(:,:,2) = 
    [17]    [10]    [15]
    [12]    [14]    [16]
    [13]    [18]    [11]

Then the indexing used in example 8 above would yield the cell array

>> C([1 2], [true false true false true false])
ans = 
    [8]    [6]    [10]
    [3]    [7]    [14]

whereas using curly braces would yield the comma-separated list

>> C{[1 2], [true false true false true false]}
ans =
     8
ans =
     3
ans =
     6
ans =
     7
ans =
    10
ans =
    14 

Take-away message / TL;DR

Logical and linear indexing are not exclusive types of indexing. Rather, they are two independent features of indexing. "Logical" refers to the type of the index values, and "linear" indicates that several dimensions are being collapsed and indexed as one. Both features can happen simultaneously.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文