罗兰关于MATLAB的艺术

将想法转化为MATLAB

MATLAB中的重复索引

索引是A.热门话题我经常写。今天我想重点讨论当有重复索引时会发生什么。

内容

访问具有重复索引的数组元素

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

vec = [-40;实验(1);π;17;42];numdups = 3;Oddlocs = 1:2:长度(VEC);locs = oddlocs(1,numdups),:);locs = locs(:) newvec = vec(locs(:))
Locs = 1 1 1 3 3 3 5 5 5 5 newvec = -40.000 -40.000 -40.000 3.1416 3.1416 3.1416 42.0000 42.0000 42.0000

正如您所看到的,因为我要求一些重复的值,Matlab将它们归还给我。

以防万一你需要一些澄清,让我解释这里发生了什么。创建我的阵列并识别我要重复的值的位置(Oddlecs.),我将这个数组重塑为列向量loc,并使用这个数组及其重复值索引到我请求的行,包括所有列(但这里只有1列)。

这是一个更简单的示例,我将进一步扩展。

潜艇= [1;3;3);newvec vec(潜艇)=
Newvec = -40.0000 3.1416 3.1416

我创建了下标,你可以看到我想让第一个元素后面跟着第三个元素两次。我们从右边开始。从语义或意义的角度来看,MATLAB创建了一个新的临时数组,提取片段vec.要求。然后,将临时数组中的值赋给输出newvec

以下是您如何从复制的列创建矩阵。首先是索引,

Threecols = vec(:,[1 1 1])%或VEC(:,一个(1,numdups)
三校= -40.000 -40.000 -40.000 2.7183 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 1]%或VEC * ONE(1,NUMDUP)
三校= -40.000 -40.000 -40.000 2.7183 2.7183 2.7183 3.1416 3.1416 3.1416 17.0000 17.0000 17.0000 42.0000 42.0000 42.0000

repmat.

threecols = repmat(矢量,1,3)
三校= -40.000 -40.000 -40.000 2.7183 2.7183 2.7183 3.1416 3.1416 3.1416 17.0000 17.0000 17.0000 42.0000 42.0000 42.0000

您也可能对。。。有兴趣repelem

请注意,您通常不需要任何可以使用较旧的计算有效完成的计算技术bsxfun,以及最近,在我看来优雅的隐式扩展行为(12)您可以使用“展开”单例尺寸。

复制元素赋值到输出

现在让我们看看如果我们在分配中重复指数,我们需要做些什么。

newvec =矢量;vec(subs) = vec(subs) + 10
Newvec = -30.000 2.7183 13.1416 17.0000 42.0000

您在这里看到的是元素1增长10且元素3的相同。但是,我们重复了元素3索引。因此,计算的右侧具有更新元素3的元素1和2份 - 以相同的方式更新,因为代码所说的那样。请记住,我说Matlab行为就像我们将右侧放入临时阵列。一旦我们完成计算右侧,Matlab就在作业上工作。头顶到底部(即使对于多维数组,也是MATLAB以列主要格式存储数据),并且它用新值替换元素1,具有新值的元素3,然后再次增加后一个时间。元素3没有10s的额外累积。但是也许你想积累重复元素的结果,但你可以简单地使用类似的东西cumsum

如何实现累积行为

您现在可以创建和使用稀疏的Matlab中的矩阵。从doc.,可以看到在构造稀疏矩阵时可以累积值。这非常方便,最终我们做了一个类似的函数,accumarray对于非稀疏数组也是如此。

一个例子的时间。我想计算像Vec(潜伏)= Vec(潜水艇)+ 10这样的东西,其中差异是我希望重复索引累积重复索引表示的10S数量。

VEC =(1:5)'句= [1;3;3);
1 . n = 1 2 3 4 5

这是上面的右侧。

VEC(潜艇)
3 .答案:a
[unquevals,〜,idxunique] =唯一(潜艇)
idxUnique = 1 2 2

请注意,我称之为函数独特的并检索第三个输出,即唯一索引在输出中出现时的实际位置。

VEC(UniqueVals)= VEC(UniqueVals)+ Accularray(IDXUNIQUE,10)
vec = 11 2 23 4 5

最后让我回到文章开始时的初始向量。我猜你现在完全明白这里发生了什么。

潜艇= [1;3;3);vec = [-40;实验(1);π;17;42];newvec =矢量;[uniquesubs, ~, idxUnique] =独特(潜艇); newvec(uniquesubs) = vec(uniquesubs) + accumarray(idxUnique, 10)
Newvec = -30.000 2.7183 23.1416 17.0000 42.0000

当处理重复索引时,你的索引挑战是什么?

不知道您在处理重复索引时是否遇到了这里没有涉及的一些挑战。请让我知道这里




发布与MATLAB®R2019b

|
  • 打印
  • 发送电子邮件

댓글

댓글을남기려면링크를클릭하여MathWorks계정에로그인하거나계정을새로만드십시오。