MATLAB中的矩阵索引

史蒂夫·埃丁斯(Steve Eddins)和罗兰·舒尔(Loren Shure)著,MathWorks

在矩阵中建立索引是一种从矩阵中选择元素子集的方法。马铃薯®有几种不仅具有强大而灵活的索引风格,还具有可读性和富有表现力的索引风格。索引是MATLAB在捕获可理解计算机程序中捕获矩阵的想法的关键。

索引还与MATLAB用户经常听到的另一个术语密切相关:矢量化。向量化意味着使用MATLAB语言构造来消除程序循环,通常会使程序运行得更快,可读性更强。在许多可能的矢量化技术中,许多依赖于MATLAB索引方法,本文将介绍其中五种方法。

索引向量

让我们从一个向量和一个下标的简单例子开始。向量:

V = [16 5 9 4 2 11 7 14];

下标可以是单个值:

v(3) %提取第三个元素ans = 9

或者下标本身可以是另一个向量:

v([1 5 6]) %提取第1、5、6个元素ans = 16 2 11

MATLAB中的冒号符号提供了一种简单的方法,可以从V中提取一系列元素:

v(3:7) %提取第三到第七个元素ans = 9 4 2 11 7

交换v的两个部分来生成一个新的向量:

V2 = V([5:8 1:4])%提取物并交换V v2 = 2 11 7 14 16 5 9 4的半部

特殊的结尾Operator是指v的最后一个元素的一种简单的简写方式:

v(end) %提取最后一个元素ans = 14

结尾操作符可以在以下范围内使用:

v(5:end) %提取倒数第5个元素ans = 2 11 7 14

您甚至可以使用算术结尾

v(2:end-1) %提取倒数第二个元素ans = 5 9 4 2 11 7

组合冒号操作符和结尾要实现各种效果,如提取每个k元素或翻转整个向量:

v(1:2:end) %提取所有奇数元素ans = 16 9 2 7 v(end:-1:1) %将元素顺序颠倒ans = 14 7 11 2 4 9 5 16

通过在等号的左侧使用索引表达式,可以取代载体的某些元素:

v([2 3 4])= [10 15 20]%替换V v = 16 10 15 20 2 11 7 14的一些元素

通常,右侧的元素数量必须与左侧索引表达式所引用的元素数量相同。但是,您可以随时使用标量子右边:

v([2 3]) = 30%用30 v = 16 30 30 20 2 11 7 14代替第二和第三元素

调用这种形式的索引赋值标量扩展

具有两个下标的索引矩阵

现在考虑索引到一个矩阵。我们将在实验中使用一个魔方:

A = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15

通常,矩阵中的索引是使用两个下标的行完成的,用于行,一个用于列。最简单的形式刚刚挑出一个元素:

A(2,4)%提取第2行中的元素,第4栏= 8

更一般地,行和列下标中的一个或两个可以是向量:

A(2:4,1:2)ANS = 5 11 9 7 4 14

一个单一的在下标位置是简写符号1:结束通常用于选择整行或整列:

A(:,end) %提取第三行ans = 9 7 6 12 A(:,end) %提取最后一列ans = 13 8 12 1

如何从矩阵中选择分散的元素常常令人困惑。例如,假设您想从a中提取(2,1)、(3,2)和(4,4)元素A([2 3 4], [1 2 4])不会做你想做的。下图说明了双下标索引是如何工作的:

从矩阵中提取散射元素需要不同的索引风格,并将我们带到我们的下一个主题。

线性索引

这表达了什么(14)做?

当您仅使用一个下标索引到矩阵A时,Matlab将A好像在长柱向量中串联出其元素,通过连续地沿着列倒在一起,如下所示:

16 5 9……8 12 1

表达式A(14)简单地提取了隐式柱向量的第14个元素。以这种方式索引到具有单个下标的矩阵,通常调用线性索引

以下是矩阵A的元素以及其线性指标:

每个元素的线性索引显示在左上角。

从图表中可以看到(14)是一样的(2、4)

单个下标可以是包含多个线性索引的向量,如:

A([6 12 15])ANS = 11 15 12

再次考虑提取(2,1),(3,2)和(4,4)元素的提取问题。您可以使用线性索引来提取这些元素:

A([2 7 16]) = 5 7 1

在这个例子中很容易看到,但是一般如何计算线性指标呢?MATLAB提供了一个函数调用次级从行和列下标转换为线性指标。您可以使用它来以这种方式提取所需的元素:

IDX = Sub2ind(大小(a),[2 3 4],[11 4])ans = 2 7 16a(Idx)ans = 5 7 1

使用线性索引的高级示例

示例1:转移矩阵的行

Matlab用户最近提出了这个问题comp.soft-sys.matlab.新闻组:如果我想移动一个m × n矩阵的行一种经过K.地方,我使用a(:,[n-k + 1:n 1:n-k]).但是,如果K.是行数的函数吗?也就是说,如果K.向量的长度是多少m?有没有一种简单快捷的方法?

定期的新闻组贡献者Peter Acklam发布了这个解决方案次级和线性索引:

%索引向量的行和列p = 1:m;q = 1: n;% index matrices for rows and columns [P, Q] = ndgrid(P, Q);% create a matrix with the shift values K = repmat(K (:), [1 n]);%用列索引Q = 1 + mod(Q+K, n)更新矩阵;%创建线性索引的矩阵ind = sub2ind([m n], P, Q);%最后,创建输出矩阵B = A(ind);

例2:设置一些矩阵元素为零

另一个Matlab用户发布了这个问题:我想获得每行的最大值,这不是一个真正的问题,但之后我想将所有其他元素设置为零。例如,这个矩阵:

1 2 3 4 5 5 6 5 7 9 8 3

应该成为:

0 0 0 4 0 0 6 0 0 9 0 0

另一个常规新闻组贡献者Brett Shoelson提供了这种紧凑的解决方案。

[Y,I] = max(A, [], 2);B = 0(大小(A));B(sub2ind(size(A), 1:length(I), I')) = Y;

逻辑索引

另一个索引的变化,逻辑索引,被证明既有用又有表达能力。在逻辑索引中,使用一个逻辑数组作为矩阵下标。MATLAB提取逻辑阵列非零值对应的矩阵元素。输出总是以列向量的形式出现。例如,(> 12)提取所有元素一种那大于12。

a(a> 12)ans = 16 14 15 13

许多matlab函数开始返回逻辑阵列并非常有用于逻辑索引。例如,您可以替换所有通过使用组合具有另一个值的数组中的元素isnan.、逻辑索引和标量展开。将所有矩阵元素B.零,使用

B(Isnan(b))= 0

或者你可以替换字符串矩阵中的所有空格str.用下划线。

str(Isspace(str))='_'

逻辑索引与...密切相关找到函数。表达式A(A> 5)相当于(找到(> 5)).您使用的表格主要是一种风格和您的代码可读性的意义,但它也取决于您是否需要计算中其他内容的实际索引值。例如,假设您要暂时替换值,执行一些计算,然后将重返原始位置的值。在此示例中,计算使用二维滤波Filter2..你这样做:

nan_locations =查找(Isnan(a));a(nan_locations)= 0;a =滤波器2(3,3),a);a(nan_locations)= nan;

我们希望本文中所示的MATLAB索引变体为您提供一种方法,可以轻松地和有效地表达算法。在MATLAB编程reptoGreire中包含这些技术和相关功能,扩展了您创建庞大,可读和矢量化代码的能力。

发布2001年


查看相关功能的文章