gpt4 book ai didi

matlab - 向量的重复元素

转载 作者:行者123 更新时间:2023-12-02 02:21:14 25 4
gpt4 key购买 nike

我有一个值向量A包含元素i ,例如:

A = [0.1 0.2 0.3 0.4 0.5];并说r = [5 2 3 2 1];

现在我想创建一个新向量 Anew包含r(i)值的重复 iA ,这样第一个 r(1)=5 Anew中的项目有值(value)A(1)新向量的长度为sum(r) 。因此:

Anew = [0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.5]

我确信这可以通过精心设计的 for 来完成。 -循环组合例如repmat ,但是有人知道如何以更顺利的方式做到这一点吗?

最佳答案

据我所知,MATLAB 中没有等效的函数可以执行此操作,尽管 Rrep这可以为你做到这一点......太嫉妒了。

无论如何,我建议的唯一方法是按照您的建议使用 repmat 运行 for 循环。但是,您也许可以这样做arrayfun相反,如果您想将其作为单行代码执行...那么从技术上讲,进行将其转换为单个向量所需的后处理就需要两个。因此,您可以尝试以下操作:

Anew = arrayfun(@(x) repmat(A(x), r(x), 1), 1:numel(A), 'uni', 0);
Anew = vertcat(Anew{:});

这本质上是用更少的代码完成for循环和复制向量的串联。我们遍历 Ar 中的每对值并吐出复制的向量。它们每个都位于元胞数组中,这就是 vertcat 的原因需要将其全部放入一个向量中。

我们得到:

Anew =

0.1000
0.1000
0.1000
0.1000
0.1000
0.2000
0.2000
0.3000
0.3000
0.3000
0.4000
0.4000
0.5000

请注意,其他人已经尝试过与您在这篇文章中所做的类似的操作:A similar function to R's rep in Matlab 。这本质上是模仿 R 执行 rep 的方式,这正是您想要做的!

<小时/>

替代方案 - 使用 for 循环

由于 @Divakar 的基准测试,我很好奇如何预分配数组,然后使用实际的 for 循环来迭代 A r 并通过索引将基准填充它。因此,使用 for 循环和索引的上述等效代码将是:

Anew = zeros(sum(r), 1);
counter = 1;
for idx = 1 : numel(r)
Anew(counter : counter + r(idx) - 1) = A(idx);
counter = counter + r(idx);
end

我们需要一个变量来跟踪我们需要在数组中插入元素的位置,该变量存储在 counter 中。我们通过每个数字要复制的元素总数来对此进行偏移,该总数存储在 r 的每个值中。

因此,此方法完全避免使用 repmat,而仅使用索引来生成复制向量。

<小时/>

基准测试(类似于 Divakar)

在 Divakar 的基准测试代码之上,除了 for 循环方法之外,我实际上还尝试在我的机器上运行所有测试。我只是将他的基准测试代码与相同的测试用例一起使用。

这些是我根据算法得到的计时结果:

情况#1 - N = 4000max_repeat = 4000

-------------------  With arrayfun
Elapsed time is 1.202805 seconds.
------------------- With cumsum
Elapsed time is 1.691591 seconds.
------------------- With bsxfun
Elapsed time is 0.835201 seconds.
------------------- With for loop
Elapsed time is 0.136628 seconds.

情况#2 - N = 10000max_repeat = 1000

-------------------  With arrayfun
Elapsed time is 2.117631 seconds.
------------------- With cumsum
Elapsed time is 1.080247 seconds.
------------------- With bsxfun
Elapsed time is 0.540892 seconds.
------------------- With for loop
Elapsed time is 0.127728 seconds.

在这些情况下,cumsum 实际上击败了 arrayfun...这正是我最初的预期。 bsxfun 击败了其他所有人,除了 for 循环。我的猜测是,由于我和 Divakar 在 arrayfun 中使用的时间不同,我们在不同的架构上运行代码。我目前正在 Mac OS X 10.9.5 MacBook Pro 计算机上使用 MATLAB R2013a 运行测试。

正如我们所见,for 循环要快得多。我知道一个事实,当涉及到 for 循环中的索引操作时,JIT 就会发挥作用并为您提供更好的性能。

关于matlab - 向量的重复元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26064172/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com