【问题标题】:Element-wise array replication in MatlabMatlab中的元素数组复制
【发布时间】:2010-12-29 04:57:22
【问题描述】:

假设我有一个一维数组:

a = [1, 2, 3];

是否有一个内置的 Matlab 函数,它接受一个数组和一个整数 n 并复制每个 数组元素n次?

例如调用replicate(a, 3) 应该返回[1,1,1,2,2,2,3,3,3]

请注意,这与repmat 完全不同。我当然可以通过对每个元素执行repmat 并连接结果来实现replicate,但我想知道是否有更有效的内置函数。

【问题讨论】:

    标签: arrays matlab repeat run-length-encoding elementwise-operations


    【解决方案1】:

    我是KRON 函数的粉丝:

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

    您还可以查看this related question(处理复制二维矩阵的元素)以了解涉及矩阵索引的其他一些解决方案。这是一个这样的解决方案(灵感来自Edric's answer):

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

    【讨论】:

    • 多么好的解决方案,但是如果 N 是 a 元素的频率矩阵,意味着 N 的每个元素都对应于 a 的一个元素呢?
    • @ghedas:地址是here,如果你还没有看到的话。
    【解决方案2】:
    a = [1 2 3];
    N = 3;
    
    b = reshape(repmat(a,N,1), 1, [])
    

    【讨论】:

    • kron不同,这个方案是纯粹的内存管理,不会把乘法拖进去。
    【解决方案3】:

    如果你有图像处理工具箱,还有另一种选择:

    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 倍)。
    【解决方案4】:
    % 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));
    

    【讨论】:

      【解决方案5】:
      >> n=3;
      >> a(floor((0:size(a,2)*n-1)/n)+1)
      
      ans =
      
           1     1     1     2     2     2     3     3     3
      

      【讨论】:

        【解决方案6】:

        一些异国情调的替代品。诚然,比有用更有趣:

        1. meshgrid 的(第一个)结果分配给一个向量:

          b = NaN(1,numel(a)*n); %// pre-shape result
          b(:) = meshgrid(a,1:n);
          
        2. 构建一个矩阵,乘以a 得到结果:

          b = a * fliplr(sortrows(repmat(eye(numel(a)),n,1))).';
          
        3. 使用ind2sub 生成索引:

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

        【讨论】:

          【解决方案7】:

          截至 R2015a,有一个built-in and documented function to do this, repelem

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

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

          B = repelem(A,N1,N2)
          

          不再需要kron 或其他技巧!

          更新:与其他快速方法的性能比较,请参阅问答Repeat copies of array elements: Run-length decoding in MATLAB

          【讨论】:

          • 在 R2015a 发布之前你是怎么知道的?!
          • @LuisMendo 预发布。我几乎和 accumarray 一样喜欢阅读发行说明。 :)。但我立即删除了我的答案,然后在发布当天取消删除,以免违反预发布条款。
          猜你喜欢
          • 1970-01-01
          • 2018-12-03
          • 2013-04-04
          • 2015-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-27
          相关资源
          最近更新 更多