使用索引值的环移

circshift using index values

我一直在寻找一种使用索引值进行环移的方法。

我知道我可以使用 circshift 命令移动所有值,见下文

a=[1:9]
b=circshift(a,[0,1])

但是我如何将每第 3 个值移到 1 之上? 例子: 注:变量a可以任意长度

a=[1,2,30,4,5,60,7,8,90] %note variable `a` could be any length

我正在努力让 b 成为

b=[1,30,2,4,60,5,7,90,8]  % so the values in the index 3,6 and 9 are shifted over 1.

您将无法使用 circshift 的标准用法来执行此操作。还有其他几种方法可以解决这个问题。这里只是一些。

使用mod创建索引值

您可以使用 mod 从位置 3:3:end 的索引值中减去 1,并将 1 添加到位置 2:3:end.[=29= 的索引值]

b = a((1:numel(a)) + mod(1:numel(a), 3) - 1);

说明

1:numel(a) 上调用 mod 3 会产生以下序列

mod(1:numel(a), 3)
%  1     2     0     1     2     0     1     2     0

如果我们从这个序列中减去 1,我们得到给定索引"shift"

mod(1:numel(a), 3) - 1
%   0     1    -1     0     1    -1     0     1    -1

然后我们可以将这个移位添加到原始索引

(1:numel(a)) + mod(1:numel(a), 3) - 1
%   1     3     2     4     6     5     7     9     8

然后将a中的值赋给b中的这些位置。

b = a((1:numel(a)) + mod(1:numel(a), 3) - 1);
%   1    30     2     4    60     5     7    90     8

使用 reshape.

另一种选择是将数据重塑为 3 x N 数组并翻转第 2 行和第 3 行,然后重塑回原始大小。 此选项仅在 numel(a) 可被 3 整除时有效。

tmp = reshape(a, 3, []);

% Grab the 2nd and 3rd rows in reverse order to flip them
b = reshape(tmp([1 3 2],:), size(a));