如何重复向量的每个第3个元素?

gui*_*ion 2 arrays matlab vectorization

我有这样的矢量:

h = [1,2,3,4,5,6,7,8,9,10,11,12]
Run Code Online (Sandbox Code Playgroud)

我想重复每一个第三个元素:

h_rep = [1,2,3,3,4,5,6,6,7,8,9,9,10,11,12,12]
Run Code Online (Sandbox Code Playgroud)

如何在MATLAB中优雅地完成这项工作?实际的数组是巨大的,所以理想情况下我不想写一个for循环.有没有矢量化的方法来做到这一点?

ray*_*ica 6

一种方法是使用repelem版本R2015b中发布的最近函数,您可以在向量中重复一定次数的每个元素.在这种情况下,指定一个向量,其中每个第三个元素为2,其余值为1作为重复相应元素的次数,然后使用函数:

N = numel(h);
rep = ones(1, N);
rep(3:3:end) = 2;
h_rep = repelem(h, rep);
Run Code Online (Sandbox Code Playgroud)

使用您的示例:h = 1 : 12,我们得到:

>> h_rep

h_rep =

     1     2     3     3     4     5     6     6     7     8     9     9    10    11    12    12
Run Code Online (Sandbox Code Playgroud)

如果repelem您无法使用,那么巧妙使用cumsum可能有所帮助.基本上,请注意,对于每三个元素,下一个元素是前一个元素的副本.如果我们有一个指标向量,[1 1 1 0]其中1我们想要复制的位置,并0告诉我们复制最后一个值,使用累积和或cumsum该向量的重复版本 - 确切地1 + (numel(h) / 4)将给出我们需要索引的确切位置h.因此,创建一个向量的向量,它是h添加的长度,1 + (numel(h) / 4以确保我们为重复元素创建空间,然后确保在应用之前将每个第四个元素设置为0 cumsum:

N = numel(h);
rep = ones(1, N + 1 + (N / 4));
rep(4:4:end) = 0;
rep = cumsum(rep);
h_rep = h(rep);
Run Code Online (Sandbox Code Playgroud)

从而:

>> h_rep

h_rep =

     1     2     3     3     4     5     6     6     7     8     9     9    10    11    12    12
Run Code Online (Sandbox Code Playgroud)

最后一个建议(感谢用户@bremen_matt)将reshape你的向量转换为矩阵,使其有3行,复制最后一行,然后将得到的重复矩阵重新整形为单个向量:

h_rep = reshape(h, 3, []);
h_rep = reshape([h_rep; h_rep(end,:)], 1, []);
Run Code Online (Sandbox Code Playgroud)

我们再次获得:

>> h_rep

h_rep =

     1     2     3     3     4     5     6     6     7     8     9     9    10    11    12    12
Run Code Online (Sandbox Code Playgroud)

当然,上面代码的明显警告是向量的长度h可以被4整除.


bre*_*att 6

(根据rayryeng的正确观察修改)......

另一种解决方案是使用重塑功能.如果你首先将矩阵重塑为3xn矩阵......

B = reshape(h,3,[])
Run Code Online (Sandbox Code Playgroud)

然后复制最后一行

B = [B;B(end,:)]
Run Code Online (Sandbox Code Playgroud)

最后矢量化解决方案......

B(:).'
Run Code Online (Sandbox Code Playgroud)