Replicação da matriz em termos de elemento no MATLAB
-
21-09-2019 - |
Pergunta
Digamos que eu tenha uma matriz unidimensional:
a = [1, 2, 3];
Existe uma função matlab integrada que leva uma matriz e um número inteiro n
e replica cada elemento da matriz N vezes?
Por exemplo, chamando replicate(a, 3)
deve voltar [1,1,1,2,2,2,3,3,3]
.
Observe que isso não é o mesmo que repmat
. Eu certamente posso implementar replicate
fazendo repmat
Em cada elemento e concatenando o resultado, mas estou me perguntando se há uma função incorporada que é mais eficiente.
Solução
A partir de R2015A, existe um Função embutida e documentada para fazer isso, repelem
:
repelem
Replicar elementos de uma matriz.
W = repelem(V,N)
, com vetorV
e escalarN
, cria um vetorW
onde cada elemento deV
é repetidoN
vezes.
O segundo argumento também pode ser um vetor do mesmo comprimento que V
Para especificar o número de repetições para cada elemento. Para replicação 2D:
B = repelem(A,N1,N2)
Não há necessidade de kron
Ou outros truques mais!
ATUALIZAR: Para uma comparação de desempenho com outros métodos rápidos, consulte as perguntas e respostas Repita cópias dos elementos da matriz: decodificação de run-comprimento no MATLAB.
Outras dicas
Eu sou um fã do Kron função:
>> a = 1:3;
>> N = 3;
>> b = kron(a,ones(1,N))
b =
1 1 1 2 2 2 3 3 3
Você também pode olhar para esta pergunta relacionada (que lidou com elementos replicantes das matrizes 2-D) para ver algumas das outras soluções envolvendo indexação da matriz. Aqui está uma dessas solução (inspirada por Resposta de Edric):
>> 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
Algumas alternativas exóticas. Reconhecidamente mais engraçado do que útil:
Atribuir o (primeiro) resultado de
meshgrid
para um vetor:b = NaN(1,numel(a)*n); %// pre-shape result b(:) = meshgrid(a,1:n);
Construir uma matriz que se multiplicou por
a
dá o resultado:b = a * fliplr(sortrows(repmat(eye(numel(a)),n,1))).';
Usar
ind2sub
Para gerar os índices:[~, ind] = ind2sub([n 1],1:numel(a)*n); b = a(ind);
Se você tem a caixa de ferramentas de processamento de imagem, há outra alternativa:
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));