• MATLAB中的矩阵索引


    利用矩阵的索引取出原矩阵的子集元素是一种有效的方式。MATLAB的多种索引不但类型强大、灵活,而且表达清晰易读。在理解电脑MATLAB编程方面。体会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) % 取出从第3到第7个的所有元素
    ans =
    9 4 2 11 7
    向量V的两个分区可以组成一个新的新的向量:
    v([5:8 1:4])
    ans =
    1 至 7 列
    2 11 7 14 16 5 9
    8 列
    4
    特殊符号”end"快速取出向量v中最后一个元素:
    v(end) % 取出最后一个元素
    ans =
    14
    v(5:end) % 取出从第5个到最后一个元素
    ans =
    2 11 7 14
    你甚至可以对符号”end“进行数学运算:
    v(2:end-1) % 取出从第2个到向量倒数第2个的所有元素
    ans =
    5 9 4 2 11 7
    将冒号":'和”end"组合起来可以产生巨大效果,例如取出一段范围内以k为步进的向量元素集
    v(1:2:end) % 取出奇数下标的元素
    ans =
    16 9 2 7
    v(end:-1:1) % 逆序取出所有元素
    ans =
    1 至 7 列
    14 7 11 2 4 9 5
    8 列
    16
    通过在等式左边使用索引表达式,你可以替换向量中特定元素:
    v([2 3 4]) = [10 15 20]% 替代v中一些特定元素
    v = 16 10 15 20 2 11 7 14
    等式右边的元素必须和等式左边下标对应的元素保持一致。然而,你可以在等式右边用标量
    v([2 3]) = 30 % 第2和第3元素重新赋值为30
    v =
    1 至 7 列
    16 30 30 4 2 11 7
    8 列
    14
    这种索引赋值称作 标量扩张

    带有两个下标的索引矩阵

    现在考虑矩阵索引的用法,我们用一个魔力方阵来做实验:
    A = magic(4)
    A=
    16 2 3 13

    5 11  10  8
    
    9 7   6  12
    
    4 14  15  1
    

    通常,矩阵索引用两个下标 --一个作为行下标,一个作为列下标,最简单方法取出矩阵一个元素如下:
    A(2,4) % 取出第2行,第4列对应元素
    ans =
    8
    更为常用的是,一个行下标或列下标可以是向量:
    A(2:4,1:2)
    ans =
    5 11
    9 7
    4 14
    在下标位置的一个符号":",是对”1:end“方便快捷的替代,总是用来选整行或整列元素:
    A(3, :) % 取出完整的第3行
    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])取出的显然不是你所想要的,下面([2 4], [1 2 4])是如何工作的:
    A([2 3 4], [1 2 4])
    ans =
    5 11 8
    9 7 12
    4 14 1

    线性索引

    表达式A(14)表示什么呢?
    当你用带一个下标的索引取出矩阵元素时,MATLAB默认矩阵中所有元素一个长列向量来存储数据,如下:
    16
    5
    9
    ...
    8
    12
    1
    因此,表达式A(14)取出列向量的第14个元素,用单一下标取出数据元素的方式称作:线性索引
    你可以知道A(14)和A(2,4)等价
    单一下标可以是一个多个线性索引组合而成的向量,如下:
    A([6 12 15])
    ans =
    11 15 12
    再次考虑这个问题:从矩阵A中提取(2,1),(3,2), 和(4,4) 对应的元素?你可以通过用线性
    索引来取出这些元素:
    A([2 7 16])
    ans =
    5 7 1
    从这个例子中你可以很简单看出索引,但是长远的你如何计算线性索引呢?MATLAB提供一个函数:sub2ind,该函数能够将特定行列下标转换为线性索引。你可以用这种方式提取特定元素:
    idx = sub2ind(size(A), [2 3 4], [1 2 4])
    ans =
    2 7 16
    A(idx)
    ans =
    5 7 1
    关于用线性索引的最新例子:
    例1:平移一个矩阵的数排
    一个MATLAB用户最近在comp.soft-sys.matlab新手组提出一个问题:
    如果我想移动矩阵m-n列k次,我用A(:,[n-k+1:n1:n-k])实现,当如果k是一个数字集怎么办?也就是说,倘若k是一个长度为m的向量呢,是否有快捷方便的办法做到呢?

    社区新手组贡献者,Peter Acklam, 提出了用”sub2ind“和线性索引来解决:

    %这个例子我没看,以后有工夫再研究
    % index vectors for rows andcolumns
    p = 1:m;
    q = 1:n;
    % index matrices for rows andcolumns
    [P, Q] = ndgrid(p, q);
    % create a matrix with the shiftvalues
    K = repmat(k(:), [1 n]);
    % update the matrix with the columnindexes
    Q = 1 + mod(Q+K-1, n);
    % create matrix of linear indexes
    ind = sub2ind([m n], P, Q);
    % finally, create the output matrix
    B = A(ind);
    

    例2:使矩阵的一些元素为0

    另一个MATLAB用户提出这个问题。
    我想获取每一个的最大值,这不是什么大问题,但是之后我想令其他元素为0,比如,矩阵:
    1 2 3 4

    5 5 6 5

    7 9 8 3

    should become:

    0 0 0 4

    0 0 6 0

    0 9 0 0

    另一个社区贡献者,BrettShoelson,提出了解决办法:

    %这里用到的函数很简单,搜一下就知道用法啦
    [Y,I]= max(A, [], 2);%获取每一行最大值,结果 存在列向量Y中,I里存的是每行最大值的列位置。
    
    B = zeros(size(A));%建立一个和A同等大小的矩阵
    
    B(sub2ind(size(A), 1:length(I),I')) = Y;%将三个最大值分别放到线性索引对应的位置上
    

    逻辑索引

    另一个索引变量,逻辑索引,已被证明其有用并且易于表达。在逻辑索引中,你可以为矩阵下标使用一个单一的逻辑数组,MATLAB取出逻辑判断为真的元素,输出经常是一个列向量。例如,A(A>2)取出矩阵A中所有大于12的元素
    A(A > 12)
    ans =
    16
    14
    15
    13
    许多MATLAB函数以“is"开头,返回逻辑数组,这对于逻辑索引非常有用。

    例如,你可以用另外一个值来替代一个数组中所有不是数字的数:NaNs,这里使用函数isnan,逻辑索引和标量扩张。矩阵B中所有NaN元素都赋值为0
    B(isnan(B)) = 0

    或者亦可以将字符串矩阵中所用空格用下划线‘_'代替

    str(isspace(str)) = '_'
    逻辑索引和函数find关系紧密。表达式A(A>5)等价于A(find(A>5))。你所用哪种主要取决于你的风格和代码可读性

    但是这种取舍也取决于是否你需要实际的索引去做一些其他的计算。

    例如,假定你想暂时将矩阵中NaN(不为数字的元素)赋值为0,做一些运算。之后将NaN(不为数字的元素)重新放回矩阵原位置。在这个例子中,2维滤除使用函数:filter2,你可能会这样做:

    nan_locations = find(isnan(A));
    A(nan_locations) = 0;
    A = filter2(ones(3,3), A);
    A(nan_locations) = NaN;
    

    我们希望在这一篇文章中列举的MATLAB索引变量能够给你一个感觉,你可以高效精简的描述算法。在你的MATLAB编程中,使用这些技术和与之相关的函数能够增强你创造出熟练地、易读地和矢量化的代码的能力.

    参考文献

    王茂春于2015年12月27日 东六实验室
    MATLAB中的矩阵索引

  • 相关阅读:
    7. Scrapy的高级用法
    6. Scrapy的基本用法
    5. 基于Selenium实现爬虫
    4. 异步爬虫
    3. 数据解析
    2. requests的使用
    1. 爬虫概述
    03-Servlet初识
    Flask框架基础(1)
    登录mysql时,报错ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)
  • 原文地址:https://www.cnblogs.com/sggggr/p/14804445.html
Copyright © 2020-2023  润新知