Поэлементная репликация массива в Matlab
-
21-09-2019 - |
Вопрос
Допустим, у меня есть одномерный массив:
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
Несколько экзотических альтернатив.По общему признанию, скорее забавно, чем полезно:
Назначьте (первый) результат
meshgrid
к вектору:b = NaN(1,numel(a)*n); %// pre-shape result b(:) = meshgrid(a,1:n);
Постройте матрицу, которая умножается на
a
дает результат:b = a * fliplr(sortrows(repmat(eye(numel(a)),n,1))).';
Использование
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));