Поэлементная репликация массива в Matlab

Допустим, у меня есть одномерный массив:

a = [1, 2, 3];

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

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

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


person Dima    schedule 22.12.2009    source источник


Ответы (5)


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

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

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

B = repelem(A,N1,N2)

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

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

person chappjc    schedule 10.12.2014
comment
Как вы узнали об этом до того, как вышел R2015a ?! - person Luis Mendo; 08.03.2015
comment
@LuisMendo Предварительная версия. Я люблю читать примечания к выпуску почти так же сильно, как аккумулятор. :). Но я немедленно удалил свой ответ, а затем восстановил его в день выпуска, чтобы не нарушать условия предварительного выпуска. - person chappjc; 08.03.2015

Я поклонник функции 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
person gnovice    schedule 22.12.2009
comment
какое хорошее решение, но как насчет того, чтобы N - матрица частот элементов a, означает, что каждый элемент N соответствует одному элементу a? - person ghedas; 26.11.2012
comment
@ghedas: это адрес здесь, если вы еще не видели его. - person gnovice; 16.05.2017

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

  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);
    
person Luis Mendo    schedule 27.12.2013

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

N = 3;
imresize(a, [1 N*numel(a)],'nearest')
person Andrey Rubshtein    schedule 25.01.2012
comment
На самом деле ваш код неверен. Это должно быть imresize(a, [1 N*numel(a)],'nearest') с N, а не 2. Когда вы исправите это, ваше решение будет примерно в 3 раза медленнее, чем решение KRON (и в 5 раз медленнее, чем решение для индексации a(ceil((1:N*numel(a))/N))). - person gnovice; 25.01.2012

person    schedule
comment
в отличие от kron, это решение является чисто управлением памятью и не требует умножения. - person shabbychef; 23.12.2009