Поэлементная репликация массива в Matlab - PullRequest
18 голосов
/ 22 декабря 2009

Допустим, у меня есть одномерный массив: a = [1, 2, 3];

Есть ли встроенная функция Matlab, которая принимает массив и целое число n и реплицирует каждый элемент массива n раз?

Например, вызов replicate(a, 3) должен вернуть [1,1,1,2,2,2,3,3,3].

Обратите внимание, что это совсем не то же самое, что repmat. Я, конечно, могу реализовать replicate, выполнив repmat для каждого элемента и конкатенируя результат, но мне интересно, есть ли встроенная функция, которая более эффективна.

Ответы [ 7 ]

21 голосов
/ 22 декабря 2009

Я фанат функции KRON :

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

b =

    1     1     1     2     2     2     3     3     3

Вы также можете посмотреть этот связанный вопрос (который касался репликации элементов двумерных матриц), чтобы увидеть некоторые другие решения, включающие индексирование матриц. Вот одно из таких решений (вдохновлено ответом Эдрика ):

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

b =

    1     1     1     2     2     2     3     3     3
20 голосов
/ 22 декабря 2009
a = [1 2 3];
N = 3;

b = reshape(repmat(a,N,1), 1, [])
13 голосов
/ 11 декабря 2014

Начиная с R2015a , для этого имеется встроенная и задокументированная функция , repelem:

repelem Копировать элементы массива.
W = repelem(V,N) с вектором V и скаляром N создает вектор W, где каждый элемент V повторяется N раз.

Второй аргумент также может быть вектором такой же длины, что и V, чтобы указать количество повторений для каждого элемента. Для 2D репликации:

B = repelem(A,N1,N2)

Больше не нужно kron или других трюков!

ОБНОВЛЕНИЕ: Сравнение производительности с другими быстрыми методами см. В разделе Вопросы и ответы Повторные копии элементов массива: декодирование по длине прогона в MATLAB .

3 голосов
/ 28 декабря 2013

Некоторые экзотические альтернативы. По общему признанию, скорее смешно, чем полезно:

  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);
    
3 голосов
/ 27 сентября 2012
>> n=3;
>> a(floor((0:size(a,2)*n-1)/n)+1)

ans =

     1     1     1     2     2     2     3     3     3
2 голосов
/ 25 января 2012

Если у вас есть набор инструментов для обработки изображений, есть другая альтернатива:

N = 3;
imresize(a, [1 N*numel(a)],'nearest')
1 голос
/ 13 августа 2012
% 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));
...