Вопрос

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

a = [1, 2, 3];

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

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

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

Это было полезно?

Решение

По состоянию на R2015a, существует встроенная и документированная функция для этого, repelem:

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

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

B = repelem(A,N1,N2)

Нет необходимости в kron или других трюков больше нет!

Обновить: Для сравнения производительности с другими быстрыми методами, пожалуйста, ознакомьтесь с Вопросами и ответами Повторяющиеся копии элементов массива:Декодирование по длине выполнения в MATLAB.

Другие советы

Я фанат того, что 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
a = [1 2 3];
N = 3;

b = reshape(repmat(a,N,1), 1, [])
>> n=3;
>> a(floor((0:size(a,2)*n-1)/n)+1)

ans =

     1     1     1     2     2     2     3     3     3

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

  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);
    

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

N = 3;
imresize(a, [1 N*numel(a)],'nearest')
% 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));
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top