罗兰关于MATLAB的艺术

将想法转化为MATLAB

MATLAB中的重复索引

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

内容

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

假设我想numdups复制向量中奇数位置的元素,vec

vec = [-40;实验(1);π;17;42];numdups = 3;oddlocs = 1:2:长度(vec);loc = 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将它们返回给我。

如果你需要一些澄清,让我解释一下这里发生了什么。在创建数组并确定要重复的值的位置之后(oddlocs),我将这个数组重塑为列向量loc,并使用这个数组及其重复值索引到我请求的行,包括所有列(但这里只有1列)。

下面是一个更简单的例子,我将进一步扩展它。

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

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

下面介绍如何从复制的列创建一个矩阵。首先通过索引,

Threecols = vec(:,[1 1 1])%或vec(:, ones(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

通过矩阵乘法

three ecols = vec * [1 1 1]%或vec * ones(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

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的索引。因此,计算后的右手边有元素1和更新后的元素3的2个副本——更新的方式都是一样的,因为这就是代码要做的。记得我说过MATLAB的行为就像我们把右边放入一个临时数组。一旦我们完成了右边的计算,MATLAB就可以完成任务了。从上到下(甚至对于多维数组,因为MATLAB以列主格式存储数据),它用一个新值替换元素1,用一个新值替换元素3,然后再执行一次后一个。元素3没有额外积累10秒。但是,也许您想积累重复元素的结果,但它不是那么整洁,您可以简单地使用类似的东西cumsum

如何实现积累行为

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

举个例子。我想要计算一些类似于vec(subs) = vec(subs) + 10的东西,不同的是,我想要重复指标将重复指标表示的10的个数相加。

if ((1 = 1) and (1 = 1))3;3);
1 . n = 1 2 3 4 5

右边和上面一样。

vec(潜艇)
3 .答案:a
[uniquevals, ~, idxUnique] =独特(潜艇)
idxUnique = 1 2 2

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

vec(uniquevals) = vec(uniquevals) + accumarray(idxUnique, 10)
1 . Vec = 1 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アカウントにサインインするか新しいMathWorksアカウントを作成します。