【问题标题】:MATLAB: How does the syntax (:) work?MATLAB:语法 (:) 是如何工作的?
【发布时间】:2011-02-12 00:41:26
【问题描述】:

举个例子:

>> I=[2 1 3;3 2 4]

I =

     2     1     3
     3     2     4

>> I(:)

ans =

     2
     3
     1
     2
     3
     4

>> I(1:2)

ans =

     2     3

为什么I(:) 返回一个列向量,而I(1:2) 返回一个较短的行向量?

【问题讨论】:

  • 我闻到了旧版支持的味道。 Matlab充满了那种东西。
  • @Mike,这不是遗产。 Matlab 是一种与 C、C++、Java、Python 等完全不同的语言。它适用于数学家(他们习惯于从 1 开始索引),而不是程序员。虽然它本身很有用(它有很好的矩阵支持),但它所做的一些事情(比如不缓存函数和为每个函数调用重新打开/关闭文件)使它不适合原型设计。
  • @Mike:实际上,我认为(:) 语法相对新,而不是旧的保留语法。
  • 最后一个问题:为什么I(:)是列向量,而I(3:4)是行向量?
  • @gnovice:我认为(1:2) 语法是遗留问题。 Matlab 中的许多其他事物更喜欢将列向量作为其一维数据。

标签: matlab syntax subscript colon matrix-indexing


【解决方案1】:

(:) 语法在用作等式右侧的索引时,是一个 special operation,它将任意维度的整个矩阵重塑为单个列向量。因此,以下两行代码给出了相同的结果:

a = I(:);               % Create a column vector with ":"
a = reshape(I, [], 1);  % Create a column vector with RESHAPE

当数字值包含在单个冒号的任一侧时,它表示数组中的linear indices 范围。所以I(1:2) 从I 中选择第一个和第二个元素(即第一列中的值)。要记住的一件事是语法1:2 实际上创建了一个向量[1 2],因此I(1:2) 与I([1 2]) 相同。由于线性索引[1 2] 是一个行向量,因此返回值的形状为行向量[2 3]。如果使用索引I([1; 2])或I((1:2).'),线性索引是列向量,所以返回的值会被整形为列向量[2; 3]。

当您有多个用逗号分隔的索引时,索引将应用于被索引矩阵的不同维度。例如,I(1:2, 1:2) 将返回 2×2 矩阵 [2 1; 3 2]。索引中的第一个1:2 应用于行,因此选择了第一行和第二行。索引中的第二个1:2 应用于列,因此选择了第一列和第二列。

描述 colon operator 和 matrix indexing 的 MATLAB 文档应该可以帮助您更好地了解如何有效地使用 :。

【讨论】:

  • 我仍然认为它们是同一回事,不是吗?
  • 所以I(1:2) 只选择第一列中的值,而I(:) 选择矩阵中的所有值,这有点合理吗?
  • @user198729, I(1:2) 选择前两个元素;在您的特定情况下,它们恰好位于第一列。如果你有一个 1x2 矩阵,那么它会给你第一行。看我的回答。至于合理性,我不喜欢它(我发现它很混乱,因为我来自 C/C++ 背景并期待不同的东西),但这种事情真的很主观。
  • 但是为什么I(:)是列向量,而I(3:4)是行向量?它们应该是同一类型的 IMO。
  • @user198729:我在回答中添加了一些解释,指出线性索引的形状如何决定输出的形状。由于索引: 没有实际形状,I(:) 的输出被(任意)选择为列向量。
【解决方案2】:

(:) 沿列向量化矩阵,即沿列读取的元素被连接成单个列向量。 a:b:c 返回从a 到c 的数字序列,增量为b。如果省略b,则默认设置为1。

序列a:b:c 可用于沿列线性索引矩阵。如果用于索引多维数组,则它会选择沿该维度的元素。例如

I(1,2:3) 

返回由I的行1和列2:3组成的矩阵,即[1 3]

此外,我们可以通过任何方式得出一个索引,并将其用于索引 I。

index = [1 2 3];
disp(I(index));

上面以列优先顺序(沿列)显示前三个元素,即[2 ; 3 ; 1]

【讨论】:

  • (a:b:c) 怎么样? ()这里不能错过对比。
【解决方案3】:

Matlab 索引示例

[行,列] = 大小(M); % M 是一个 rows x cols 矩阵

访问第 i 行第 j 列的条目:

x = M(i,j);

访问第 i 行上的所有项目:

r = M(i,:);

访问列 j 上的所有项目:

c = M(:,j);

访问第 i 行第 j 列的条目,将 M 视为向量:

x = M(行*(j-1)+i);

从第 i 行到第 j 行,从第 p 列到第 q 列访问子矩阵:

S = M(i:j,p:q);

访问整个矩阵(冗余):

M = M(:,:);

说明
冒号运算符要么给出一个索引范围(1:2 是 1 到 2 范围内的索引,包括,而 3:5 给出范围 3、4、5),或者如果没有范围,它给出给定维度的整个范围被指定。

这与仅使用单个索引对矩阵进行索引的事实相结合,可以为您提供单步执行这么多条目所产生的条目(沿行向下,增加列并在最后一行之后重置行)而不是只给你指定的行/列会导致你的观察。

【讨论】:

  • 在我的帖子中I只有2行,所以我认为(:)="所有索引"和(1:2)="所有索引",有什么区别?
  • 1:2 仅表示索引 1...2 包括在内(所以 1 和 2)。同样,2:5 将是索引 2,3,4,5。如果您省略了带有冒号的索引标记,那么它只会被解释为“所有索引”。
  • 哦,你的解释现在有道理了。但是最后一个问题,为什么I(:)是列向量,而I(3:4)是行向量?
  • @user198729,两者都应该给你 col 向量(看看当你尝试将它相乘时会发生什么);我认为这可能只是它的显示方式,尽管我真的不确定。
  • @gnovice 终于给出了矢量问题的原因,但非常感谢!
猜你喜欢
  • 2021-06-15
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 1970-01-01
相关资源
最近更新 更多