matlab核心知识点-索引index运用

目录

1. 标量index基础

要求

一般写法

索引写法

2. 向量index基础

要求

一般写法

索引写法

3. index进阶

4. index运用

5. Why index ?

普通写法

index写法

6. 交流讨论


一个用matlab写代码的人,不会用索引,就如同不会骑自行车的人在推自行车。

matlab的很多函数的返回值都可以提供索引,方便后续操作。

1. 标量index基础


要求

已知矩阵a,设a的第1行的最小值为x,其所在列为第k列,记a的第2行第k列元素为y,求x与y的乘积。


一般写法

将a的第一行第一列的元素赋值给x,并初始化位置标记position为1,从第2列开始搜索,如果有元素小于x,就更新x和position

a = [3 9 4 5 2 7; 6 8 3 3 1 4];
x = a(1,1);
position = 1;
for i = 2: length(a)
    if a(1, i) < x
        x = a(1, i);
        position = i;
    end
end
y = a(2,position);

索引写法

这里的a(1,:)表示的是矩阵a的第一行,函数min会将输入向量的最小值传给x,最小值的索引传给index

a = [3 9 4 5 2 7; 6 8 3 3 1 4];
[x, index] = min(a(1,:));
y = a(2, index);

在工作区里观察各个变量可以发现,index的值是5,是一个标量。

事实上,这里的index也可以换成向量。

2. 向量index基础


要求

找出矩阵a的第1行中小于4的元素


一般写法

设置一个空向量find,遍历矩阵a的第1行,如果有元素小于4,就将它放入find向量中

a = [3 9 4 5 2 7; 6 8 3 3 1 4];
find = [];
for i = 1: length(a)
    if a(1, i) < 4
        find = [find a(1,i)];
    end
end

索引写法

a = [3 9 4 5 2 7; 6 8 3 3 1 4];
index = a(1,:) < 4;
find = a(1, index);

这里a(1,:)的值为[3 9 4 5 2 7],是一个一维向量。

a(1,:) < 4会将该向量中的每一个值与4进行比较,返回一个长度与a(1,:)相同的布尔向量,0表示对应位置的值不小于4,1表示对应位置的值小于4。

所以index的值为 [1 0 0 0 1 0]

a(1, [1 0 0 0 1 0])的实际意义:首先取出a矩阵的第一行,接着按照向量[1 0 0 0 1 0]取出对应位置为1的值

3. index进阶与运用


进阶

结合上述两点,可以知道下面的b和c是相等的,结果都是[9 4]

a = [3 9 4 5 2 7];            %一维向量
b = a([2 3])                  %标量写法
c = a(logical([0 1 1 0 0 0])) %向量写法

这里说明一下,标量写法不是说一次只能取一个值,在这里标量写法同时取了两个值。

这里logical的意思是将普通向量转换成为布尔向量,所有为0的值变为False,所有不为0的值变为True。只有布尔向量才能进行正常的index索引操作。

因为logical函数,所以下面这3句也是等价的

c = a(logical([0 1 1 0 0 0]))
d = a(logical([0 2 3 0 0 0]))
e = a(logical([0 4 8 0 0 0]))

运用

对于下面代码的理解欢迎在评论区讨论~

%% Preparation
clear
a = [3 9 4 5 2 7; 
     6 8 3 3 1 4;
     7 2 2 6 3 5];

%% Example 1 
% Abbreviated
b_Abbreviated = a(:,a(1,:)<4); 
% General
index = a(1,:) < 4;
b_General = a(:,index);

%% Example 2
% Abbreviated
c_Abbreviated = a(a(:,4)>3,:); 
% General
index = a(:,4) > 3;
c_General = a(index,:);

%% Example 3
d_Abbreviated = a;
d_General = a;
% Abbreviated
d_Abbreviated(a(:,4)>3, a(1,:)<4) = NaN; 
% General
index1 = a(:,4) > 3;
index2 = a(1,:) < 4;
d_General(index1,index2) = NaN;

实际的应用场景会比我的例子复杂很多,但是万变不离其宗,掌握索引你就掌握了matlab的灵魂。

5. Why index ?

很多人看了我写这么多,可能感觉index也没什么用,也就是把原本五六行代码变成了两三行代码,又不好理解。

其实不然,当数据量增大的时候,使用索引的方法的运行速度会是普通写法的数十倍。


要求

有一个6000*6000的随机矩阵,矩阵元素的范围在0到1之间。现需将该矩阵中小于0.5的元素赋值为0。


普通写法

clear
a = rand(6000,6000);      % 生成0-1的6000*6000的随机浮点数矩阵
for i = 1: 6000           % 遍历行
    for j = 1: 6000       % 遍历列
        if a(i,j) < 0.5   % 判断当前元素是否小于0.5
            a(i,j) = 0;   % 对满足条件的元素赋值
        end
    end
end

index写法

clear
a = rand(6000,6000);  % 生成0-1的6000*6000的随机浮点数矩阵
matrix = a < 0.5;     % 得到小于0.5的索引矩阵
a(matrix) = 0;        % 通过索引矩阵对满足条件的元素执行赋值

在我的电脑上,普通写法需要运行3.8s,而索引写法只需要0.38s。

为什么索引写法的效率会这么高呢?我认为他可能是并行执行的。

普通写法是遍历了a(i,j)才能接着遍历a(i,j+1),相当于一个人在数36000000个元素,每次数,都需要判断这个元素是不是小于0.5,如果小于还需要对这个元素执行赋值操作。

而索引写法是并行遍历,遍历的元素没有先后关系,相当于七八个人(线程)在一起数打乱的36000000个元素,把小于0.5的元素的位置记下来。接着这七八个人一起给记录的位置赋值。

为了更直观地说明这个问题,我制作了两幅GIF如下。

可以看到同样是20*20的矩阵,单线程顺序遍历的速度远不如多线程随机遍历的速度。

6. 交流讨论

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Toblerone_Wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值