Matlab中的逐元素数组复制

18
假设我有一个一维数组:a = [1, 2, 3]; 是否有Matlab内置的函数,可以将数组和整数 n 作为输入,然后将数组中的每个元素复制n次?
例如调用replicate(a, 3)应返回[1,1,1,2,2,2,3,3,3]
请注意,这与repmat完全不同。 我当然可以通过对每个元素进行repmat并连接结果来实现replicate,但我想知道是否有更高效的内置函数。
7个回答

21

我是KRON函数的粉丝:

>> a = 1:3;
>> N = 3;
>> b = kron(a,ones(1,N))

b =

    1     1     1     2     2     2     3     3     3

你还可以查看这个相关问题(它处理了复制二维矩阵元素的问题),以查看涉及矩阵索引的其他解决方案。以下是一个这样的解决方案(灵感来自Edric的答案):

>> b = a(ceil((1:N*numel(a))/N))

b =

    1     1     1     2     2     2     3     3     3

这是一个不错的解决方案,但如果N是a元素频率的矩阵,也就是说N的每个元素都对应着a的一个元素,那该怎么办呢? - ghedas
@ghedas:如果你还没有看到的话,这里已经解决了这个问题(https://dev59.com/ynI-5IYBdhLWcg3wMFS0)。 - gnovice

20
a = [1 2 3];
N = 3;

b = reshape(repmat(a,N,1), 1, [])

5
不同于kron,这个解决方案纯粹是内存管理,不会将乘法运算引入其中。 - shabbychef

14

从R2015a开始,Matlab有一个内置且被记录的函数repelem可以完成这个任务:

repelem 重复数组中的元素。
    对于向量 V 和标量 NW = repelem(V,N) 创建一个向量 W,其中每个 V 的元素都重复了 N 次。

第二个参数也可以是与 V 相同长度的向量,以指定每个元素的重复次数。对于2D重复:

B = repelem(A,N1,N2)

不再需要使用kron或其他技巧!

更新:有关与其他快速方法的性能比较,请参见Q&A Repeat copies of array elements: Run-length decoding in MATLAB


2
在R2015a发布之前,你是怎么知道这个的?! - Luis Mendo
6
@LuisMendo 预发布版。我喜欢读发行说明,几乎和 accumarray 一样。:). 但是在发布日当天,我立即删除了我的回答,然后又取消了删除,以免违反预发布条款。 - chappjc

3
>> n=3;
>> a(floor((0:size(a,2)*n-1)/n)+1)

ans =

     1     1     1     2     2     2     3     3     3

3

一些奇特的替代方案。承认比有用更有趣:

  1. Assign the (first) result of meshgrid to a vector:

    b = NaN(1,numel(a)*n); %// pre-shape result
    b(:) = meshgrid(a,1:n);
    
  2. Build a matrix that multiplied by a gives the result:

    b = a * fliplr(sortrows(repmat(eye(numel(a)),n,1))).';
    
  3. Use ind2sub to generate the indices:

    [~, ind] = ind2sub([n 1],1:numel(a)*n);
    b = a(ind);
    

2
如果您拥有图像处理工具箱,还有另一种选择:
N = 3;
imresize(a, [1 N*numel(a)],'nearest')

实际上,你的代码有误。它应该是 imresize(a, [1 N*numel(a)],'nearest'),使用一个 N 而非 2。当你更正这个错误后,你的解决方案实际上比 KRON 解决方案慢了大约 3 倍(并且比索引解决方案 a(ceil((1:N*numel(a))/N)) 慢了5倍)。 - gnovice

1
% To get b = [1 1 1 2 2 2 3 3 3]
N = 3;
a = [1 2 3];
temp_a = a(ones(N,1),:);
b = reshape(temp_a,1,numel(temp_a));

% To get b = [1 2 3 1 2 3 1 2 3]
N = 3;
a = [1 2 3];
temp_a = a(ones(N,1),:);
b = reshape(temp_a',1,numel(temp_a));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接