洛伦谈MATLAB的艺术

将想法转化为MATLAB

MATLAB中的重复索引

索引是一种热门话题我时不时地写一些关于他的文章。今天我想重点讨论当存在重复索引时会发生什么。

目录

使用重复索引访问数组元素

假设我想numdups向量中奇数位置元素的副本,vec.

vec=[-40;exp(1);pi;17;42];numdups=3;oddlocs=1:2:长度(vec);locs=oddlocs(one(1,numdups),:);locs=locs(:)newvec=vec(locs(:)
locs=11 13 3 5 5 5 newvec=-40.0000-40.0000-40.0000 3.1416 3.1416 3.1416 42.0000 42.0000 42.0000

如您所见,由于我请求一些重复的值,MATLAB将它们返回给我。

为了防止您需要一些澄清,让我解释一下这里发生了什么。创建数组并确定值的位置后,我希望重复(怪人),我将此数组重塑为列向量locs,并使用此数组及其重复值索引到我请求的行,包括所有列(但这里只有一列)。

这里有一个更简单的例子,我将进一步扩展。

subs=[1;3;3];newvec=vec(subs)
newvec=-40.0000 3.1416 3.1416

我创建了我的索引,你可以看到,我希望第一个元素后面跟着第三个元素两次。让我们从右手边开始。从语义或意义的角度来看,MATLAB创建了一个新的临时数组来提取数据片段vec随后,临时数组中的值被分配给输出纽维克.

下面是如何从复制列创建矩阵。首先通过索引,

threecols=vec(:,[1])%或vec(:,个(1,个)
threecols=-40.0000-40.0000-40.0000 2.7183 2.7183 3.1416 3.1416 3.1416 17.0000 17.0000 17.0000 42.0000 42.0000 42.0000

通过矩阵乘法

threecols=vec*[1]%或vec*一(1,numdups)
threecols=-40.0000-40.0000-40.0000 2.7183 2.7183 3.1416 3.1416 3.1416 17.0000 17.0000 17.0000 42.0000 42.0000 42.0000

雷普马特.

threecols=repmat(vec,1,3)
threecols=-40.0000-40.0000-40.0000 2.7183 2.7183 3.1416 3.1416 3.1416 17.0000 17.0000 17.0000 42.0000 42.0000 42.0000

您也可能对以下内容感兴趣:重复.

请注意,您通常不需要这些技术中的任何一种来进行某些计算,而这些计算可以通过旧版本高效地完成bsxfun,而且,在我看来,最近是优雅的、隐性的扩张行为(1.,2.)您可以使用它来“扩展”单个维度。

用于分配到输出的复制元素

现在,让我们看看如果在赋值中有重复的索引,我们需要做什么。

newvec=vec;newvec(subs)=vec(subs)+10
新向量=-30.0000 2.7183 13.1416 17.0000 42.0000

你在这里看到的是元素1增加了10,元素3也增加了10。但是,我们重复了元素3索引。因此,计算的右侧有元素1和更新的元素3的2个副本,每个副本都以相同的方式更新,因为这是代码所说的。记得我说过,MATLAB行为就像我们放置右侧sid一样当我们完成右边的计算后,MATLAB将处理赋值。从上到下(即使是多维数组,因为MATLAB以列主格式存储数据),它用一个新值替换元素1,用一个新值替换元素3,然后再做一次后一次。元素3没有额外的10秒累积。但是,也许你想为重复的元素累积结果,但它不是那么整洁,你可以简单地使用累加.

如何实现积累行为

现在,您可以创建和使用稀疏的MATLAB中的矩阵。从…起医生,你可以看到,你可以在构造稀疏矩阵时积累值。这非常方便,最终我们制作了一个类似的函数,Accumaray对于非稀疏阵列也是如此。

举个例子,我想计算一些东西,比如vec(subs)=vec(subs)+10,不同的是我想重复索引累加由重复索引表示的10的数量。

向量=(1:5)'subs=[1;3;3];
向量=1 2 3 4 5

这是上面的右手边。

vec(潜艇)
ans=13
[uniquevals,~,idxUnique]=唯一(子)
唯一性=1 3 idxUnique=1 2 2

注意,我调用了这个函数唯一的并检索第三个输出,即唯一索引在输出中的实际位置。

vec(唯一)=vec(唯一)+accumarray(idxUnique,10)
vec=112345

最后让我回到文章开头的初始向量,我猜你完全理解这里发生的事情了。

subs=[1;3;3];vec=[-40;exp(1);pi;17;42];newvec=vec;[uniquesubs,~,idxUnique]=唯一(subs);newvec(uniquesubs)=vec(uniquesubs)+accumarray(idxUnique,10)
新向量=-30.0000 2.7183 23.1416 17.0000 42.0000

在处理重复索引时,您的索引难题是什么?

想知道在处理重复索引时,您是否遇到了此处未涉及的一些挑战。请告诉我在这里.




与MATLAB®R2019b一起发布

|
  • 打印
  • 发送电子邮件

评论

如需留言,请点击在这里登录到您的MathWorks帐户或创建新帐户。