005_index_in_Matlab中的数组索引

Matlab中的数组索引

1. 数组相关函数

前面我们已经介绍了关于向量、数组的一些基本约定,已经涉及了一些数组创建和操作的规则。

函数作用备注
size返回数组的大小
length返回数组的最大维度
ndims返回数组的维度数
numel返回数组的元素个数
zeros创建全零数组
ones创建全一数组
rand创建随机数组
randn创建服从正态分布的随机数组
linspace创建等差数列
logspace创建等比数列

特别还有操作符:,用于生成等差数列,如1:2:10,产生行向量[1,3,5,7,9]

还有一些没有介绍的创建函数,也很常用。

函数作用备注
eye创建单位矩阵
magic创建魔方阵
true创建逻辑1
false创建逻辑0

还有几个函数,是提取部分元素或者组合元素形成新的数组。

函数作用备注
blkdiag创建对角矩阵
diag提取对角线元素
tril提取下三角矩阵
triu提取上三角矩阵
flip翻转数组
fliplr水平翻转数组
flipud垂直翻转数组
cat拼接数组
repmat复制数组
horzcat水平拼接数组
vertcat垂直拼接数组
reshape重塑数组
squeeze去除维度为1的维度
repelem重复数组元素

这里不对这些命令进行详细介绍,需要查看帮助的,请在Matlab命令行中输入help命令,如help eyehelp magic等。要查看详细文档,可以在Matlab命令行中输入doc命令,如doc eyedoc magic等。

这里对数组元素的访问,也称为数组索引,进行一个专门的介绍。

2. 为什么要用括号

很多程序员和初学者在使用Matlab时,会有一个疑问:为什么要用括号来索引数组元素,而不是用方括号?毕竟在C、Python等语言中,我们都是用方括号来索引数组元素的。所以在第一门课程里面都是按方括号来来学习的,这是第一印象。

我在仔细调研这个问题之前就形成了一个观点:那就是Matlab把数组(矩阵)假装成一个对象,这个对象自己是一个函数,索引就是这个函数的意义。

下面,请听我的狡辩。

在Matlab中,函数的调用是用括号的,如sin(x)size(A)plot(x,y)等等。这是Matlab的基本约定,括号是函数调用的标志。那么索引数组的元素呢?也是用括号,如A(1,2)A(1:3)A(1:2:end)等等。是不是很相似?

其次,等后面我会专门写一个函数的约定,里面会讲到,Matlab里面有一个数据构造叫做cell,跟别的语言的元组非常类似,实际上Matlab函数的输入参数和输出值都是cell

比如有个函数size,他可以返回数组的大小,或者返回数组的特定维的大小。

A = magic(3); % 3 x 3
sz = size(A); % [3,3]
sz1 = size(A,1); % 3args = {A, 1};
sz2 = size(args{:}); % 3

我们再来看高维数组的索引,看看是不是有什么很一样的地方。

A = magic(3); % 3 x 3A(1,2) % 索引单个元素A(2:3,1:2) % 索引子矩阵A([1,2], [1, 3]) % 索引特定元素

那么你们猜猜,是否能够采用上面的cell的方式来索引数组呢?

A = magic(3); % 3 x 3idx = {1,2};
A(idx{:}) % 索引单个元素idx = {2:3,1:2};
A(idx{:}) % 索引子矩阵idx = {[1,2], [1, 3]};
A(idx{:}) % 索引特定元素

很可能你们会发现,这个cell的方式和数组索引的方式是一样的。

一个东西,它看起来像函数,走起来像函数,叫起来也像函数,那么它就(可能)是函数。

以上,就是我的狡辩。实际上,只要接受了这个设定,你会发现Matlab的数组索引是非常方便的,而且非常强大。

3. 索引的种类

Matlab中的数组索引可以按两种方式进行:

  1. 位置索引
  2. 逻辑索引

位置索引很简单,就是通过前面给出的cell的方式,指定数组的位置,如A(1,2)A(1:3)A(1:2:end)等等,你就想象成函数调用,按照低维至高维来制定下标范围,每个维度的下标范围必须是一个整数、整数列表、colon列表(😃。这个下标范围就是位置索引,每个索引的值都应该在 [ 1 , size ( A , i ) ] [1, \text{size}(A,i)] [1,size(A,i)]之间(请思考这句话是不是一定对。)。值得注意的是,这个位置索引的数量可以超过维数(ndims),但是超过维数的数值只能是1。(请思考为什么?

还有一个可以注意的事情是,可以降维索引,也就是不给足ndims个下标,此时,最后一个下标就会成为当前维到最高的非1的维的乘积。这个特性在后面的还会专门提到。

逻辑索引也非常简单,逻辑索引就是调用这个数组函数时,给的参数不是整数下标,而是逻辑值或者逻辑值组成的数组,这个数组索引的所有参数构成的cell元组给定的位置,true对应选中,false对应不选中。

看看上面的分析就知道,这两个索引概念跟降维索引交叉起来会形成四种索引方式:

  1. 线性(降维)位置索引
  2. 线性(降维)逻辑索引
  3. 多维位置索引
  4. 多维逻辑索引

值得注意的是,帮助文档只给出线性位置索引和多维逻辑索引的例子,但是实际上上面这几种复杂的情况都是存在的、合法的索引方式(数组函数调用方式)。

那么?我们提到的前面的一个左值和右值个数numel必须相等的约定,以及左值设定右值的对应关系应该如何取得呢?(请思考什么是对应关系

A = B
% numel(A) == numel(B)
% 请思考如何赋值?

Matlab必须以某种具备一致性的方式,访问A 和B的元素,考虑到上面我们已经搞出了这么多索引方式,这个对应关系应该如何取得呢?

4. 索引的规则

对于A(idx)这个表达式,这里的idx可以是任何合法的索引方式,那么这个表达式的值应该是什么呢?

这个问题的答案非常简单,我们已知的信息

  1. size(A)
  2. idx

那么我们选择一个什么样的方式最为合情合理呢?有没有一种索引是很容易在字面上是唯一的呢?这个问题随便拍脑袋就知道,那就是:

1:numel(A)

这个列向量及其中的部分元素构成的数组,可以唯一的确定A中元素的子集。按照A(:)这个方式,任何N维数组都可以被展开成一个列向量,这个列向量的元素就是原数组的元素,这个列向量的索引就是原数组的索引。

Matlab提供了一组函数,用于把任何一种索引方式转换成线性位置索引,这个函数就是sub2ind,这个函数的调用方式是:

ind = sub2ind(size(A), idx1, idx2, ..., idxN)

这跟下面的调用是一模一样的,我们在函数的讲解中会详细介绍。

ind = sub2ind(size(A), idx{:})

这里的idx1, idx2, ..., idxN就是idx的元素,可以是上面若干中索引的组合,当然必须确保idxsize(A)的范围是合法的(包括降维后的合法性)。

有了这个函数之后,就可以尽情地发掘Matlab的索引方式了。最终访问数字的元素,都是依靠这个函数返回值的唯一性来保证,通过这个函数(类似的逻辑),也能够保证左值和右值的对应关系。

相应地,还有一个作用相反地函数ind2sub,这个函数的调用方式是:

[idx1, idx2, ..., idxN] = ind2sub(size(A), ind)

这里左值的个数自然数个,当个数少于ndims时,最后一个下标就会成为当前维索引与所有高维维数的乘积(请思考为什么);当个数多于ndims时,多出来的下标全部都是1(这在语义上是合理的,因为这些下标对应的维度是1)。

这里举一个例子。

A = rand(3, 4, 5); % 3 x 4 x 5
s = size(A); % [3, 4, 5]ind = sub2ind(s, 2, 3, 4); % 44  如何计算得到这个值?[i1, j1, k1] = ind2sub(s, ind); % 2, 3, 4[i2, j2] = ind2sub(s, ind); % 2, 15[i3] = ind2sub(s, ind); % 44

这里的ind是如何计算得到的呢?这个问题是一个很好的思考题,可以帮助你理解sub2ind函数的作用。

ind = ( 4 − 1 ) × 3 × 4 + ( 3 − 1 ) × 3 + 2 = 44 \text{ind} = (4-1)\times 3 \times 4 + (3-1) \times 3 + 2 = 44 ind=41×3×4+(31)×3+2=44

我们的计算有两个要点:

  1. 从高维开始算,每个维度的下标都是从1开始的,所以要减去1;
  2. 不足一个高维的,递归计算下去。

此外ind2sub中下标可以是一个向量,这样就可以一次性计算多个位置的下标。此时,每个位置的向量长度必须相等,否则会报错。

A = rand(3, 4, 5); % 3 x 4 x 5
s = size(A); % [3, 4, 5]ind = [2, 3, 4]; [i1, j1, k1] = ind2sub(s, ind)% i1 = [2,3,1], j2=[1,1,2], k1=[1,1,1]ind = sub2ind(s, i1, j1, k1); % [2,3,4]

5. 逻辑索引的有趣之处

逻辑索引一般而言,会采用一个跟被索引矩阵大小相同的逻辑矩阵,这个逻辑矩阵的元素值为true或者false,true对应的位置会被选中,false对应的位置会被忽略。

那么,跟上面的位置索引一样,如果逻辑索引降维了呢?如果逻辑索引的每个维长度小于被索引矩阵的对应维度呢?

A = rand(3, 4, 5); % 3 x 4 x 5
s = size(A); % [3, 4, 5]idx = [true, false, true]; % 1 x 2B = A(idx); % 1 x 2,对应的元素是A(1,1), A(1,3)idx2 = {[true, false, true], [true, false, true]}; % 2 x 2C = A(idx2{:}) % 2 x 2,对应的元素是A(1,1), A(1,3), A(3,1), A(3,3)

这里降维和索引是怎么样的呢?这个问题是一个很好的思考题。

6. 结论

  1. Matlab的数组索引看起来非常像是函数调用,也确实可以当作函数调用来理解;
  2. 可以利用位置索引和逻辑索引来访问数组的元素;
  3. 索引的一致性可以通过sub2ind函数来验证。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/781268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3项目 引入unocss原子化

unocss是一个即时的原子CSS引擎,它可以让你用简短的类名来控制元素的样式,而不需要写复杂的CSS代码。 当然,原子样式也有很多选择,最著名的就是 Tailwind。但由于Tailwind 会生成大量样式定义,会导致全量的 CSS 文件往…

动态规划 Leetcode 674 最长连续递增序列

最长连续递增序列 Leetcode 300 学习记录自代码随想录 要点:1.dp[i]定义为nums[i]结尾的连续最长递增蓄力,则正向遍历,递推时,如果是连续序列,则只比较nums[i]和nums[i-1],若是可以不连续则可以&#xf…

组蛋白脱乙酰酶介导的胃癌肿瘤微环境特征及协同免疫治疗(多组学文献学习)

目录 ①HDAC转录组多数据NMF一次聚类 ②ACRG队列中HDAC单独NMF聚类 ③HDS评分在胃癌中的临床特征和基因组特征 ④高 HDS 可能提示胃癌的“热”肿瘤状态 ⑤HDS是胃癌免疫治疗效果的有力预测指标 ⑥单细胞转录组测序揭示了高HDS和低HDS患者的TME ⑦内皮细胞和成纤维细胞可…

Unity LineRenderer的基本了解

在Unity中,LineRenderer组件用于在场景中绘制简单的线条。它通常用于绘制轨迹、路径、激光等效果。 下面来了解下它的基本信息。 1、创建 法1:通过代码创建 using UnityEngine;public class CreateLineRenderer : MonoBehaviour {void Start(){// 创…

工作总结5

1.taro框架使用map标签出现的错误 这个问题困扰很长时间,在频繁切换页面渲染的时候出现左边不显示,我理解的是变量没有到达map标签的属性上,那我就想是不是setState太慢了,然后又用了变量,本地缓存等,都没有…

math模块篇(八)

文章目录 math.cosh(x)math.sinh(x)math.tanh(x) math.cosh(x) math.cosh(x) 是 Python 中 math 模块的一个函数,用于计算给定数值 x 的双曲余弦值。双曲余弦函数是双曲函数的一部分,它与普通的余弦函数有类似的性质,但定义在双曲空间中。 …

接口自动化框架搭建(四):pytest的使用

1,使用说明 网上资料比较多,我这边就简单写下 1,目录结构 2,test_1.py创建两条测试用例 def test_1():print(test1)def test_2():print(test2)3,在pycharm中执行 4,执行结果: 2&#xff0…

得物 AIGC 算法岗(日常实习生) 面经分享

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学,针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 最大的感…

Taskflow:子流任务(Subflow Tasking)

创建Subflow DAG任务中,有一种常见的场景,一个任务可能在执行期间产生新的任务,然后紧接着执行新任务。 之前提到的静态图就没有办法实现这样一个功能了,所以Taskflow提供了另一种流的节点:Subflow,Subflo…

node.js学习(2)

版权声明 以下文章为尚硅谷PDF资料,B站视频链接:【尚硅谷Node.js零基础视频教程,nodejs新手到高手】仅供个人学习交流使用。如涉及侵权问题,请立即与本人联系,本人将积极配合删除相关内容。感谢理解和支持,…

AQS的基本原理

AQS(AbstractQueuedSynchronizer)是一个用于构建锁和同步器的框架,许多同步器都可以通过AQS很容易并且高效的构造出来。不仅Reentrant和Semaphore是基于AQS构建的,还包括CountDownLatch、ReentrantReadWriteLock、SynchronousQueu…

ttkbootstrap界面美化系列之Notebook(四)

在简单的界面设计中,Notebook也是常用的组件之一,Notebook组件的引入可以根据标签来切换不同的界面。使得界面更有层次感,不必都挤在一个界面上。在tkinter中就有Notebook组件,在ttkbootstrap中,同样也对Notebook进行了…

周末总结(2024/03/30)

工作 接受破烂现状,改变状态 上周一周的工作都感觉是摸鱼状态,每天只有三个小时左右的时间聚焦在工作上,其他时间都在胡思乱想。但是我发现可以在工作中学习和下班相关的技术栈。我无意改变自己的工作状态,只想在5月底找好下家然后…

应用侧渲染流程

应用侧渲染流程 《Android应用程序UI硬件加速渲染环境初始化过程分析》 https://blog.csdn.net/Luoshengyang/article/details/45769759 《Android HWUI绘制流程》 https://wizzie.top/android/android_HWUI_Draw/#1-gpu%E6%B8%B2%E6%9F%93%E7%A1%AC%E4%BB%B6%E5%8A%A0%E9%…

Linux+ARM 简单环境检测---软件部分

1、前言 这个是我学习linuxARM的在做的第一个软硬件结合项目,以往的类似这种整体类项目还是光单片机的时候,linux软件部分学习了差不多快一年了,因为各种事情耽搁,这个项目一直没有静下心来完成,不过终于哈哈哈哈搞完了…

代码随想录——移除元素(Leetcode27)

题目链接 暴力&#xff1a;&#xff08;没有改变元素相对位置&#xff09; class Solution {public int removeElement(int[] nums, int val) {int len nums.length;for(int i 0; i < len; i){if(nums[i] val){for(int j i 1; j < len; j){nums[j-1] nums[j];}i…

VS2019连接MySQL

VS2019连接MySQL 下载MySQL Connector/C配置头文件&#xff0c;库文件路径配置头文件路径配置库的路径复制dll文件 MySQL的用户设置将权限赋值给新用户 编写代码往数据库写入 老师布置的作业让我们用VS2019连接MySQL实现一个小型的日志系统&#xff0c;中间踩了很多的坑&#x…

chatui工具使用记录与比较

概述 cahtui相关工具可谓是层出不穷&#xff0c;方便了我们使用各个大模型。这里我把我知道的整理下列出来&#xff0c;顺便做一比较。 简单比较 openWebUI&#xff0c;star 11.1k&#xff0c;仿chatgpt风格&#xff0c;支持openapi、可以对接Ollama进行对话&#xff0c;功能…

Finetuned Language Models Are Zero-Shot Learners

Abstract 本文探索了一种简单的方法来提升语言模型的零样本(zero-shot)学习能力。我们发现 指令微调(instruction tuning) 显著提高了未见任务的零样本性能。 指令微调:即在一组通过指令描述的数据集上对模型进行微调我们对一个 137B 参数的预训练模型在 60 个 NLP 任务上…

springboot婚庆系统

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于婚庆系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了婚庆系统&#xff0c;它彻底改变了过去传统的管理方式…