Pergunta

Minha pergunta é semelhante a isso 1, mas eu gostaria de replicar cada elemento de acordo com uma contagem especificada em uma segunda matriz do mesmo tamanho.

Um exemplo disso, digamos que eu tive uma matriz v = [3 1 9 4], Eu quero usar rep = [2 3 1 5] para replicar o primeiro elemento 2 vezes, o segundo três vezes, e assim por diante para obter [3 3 1 1 1 9 4 4 4 4 4].

Até agora, estou usando um loop simples para fazer o trabalho. Isso é com o que eu comecei:

vv = [];
for i=1:numel(v)
    vv = [vv repmat(v(i),1,rep(i))];
end

Consegui melhorar o espaço pré -alocado:

vv = zeros(1,sum(rep));
c = cumsum([1 rep]);
for i=1:numel(v)
    vv(c(i):c(i)+rep(i)-1) = repmat(v(i),1,rep(i));
end

No entanto, ainda sinto que deve haver uma maneira mais inteligente de fazer isso ... obrigado

Foi útil?

Solução

Aqui está uma maneira de eu gostar de conseguir isso:

>> index = zeros(1,sum(rep));
>> index(cumsum([1 rep(1:end-1)])) = 1;

index =

     1     0     1     0     0     1     1     0     0     0     0

>> index = cumsum(index)

index =

     1     1     2     2     2     3     4     4     4     4     4

>> vv = v(index)

vv =

     3     3     1     1     1     9     4     4     4     4     4

Isso funciona primeiro criando um vetor de índice de zeros do mesmo comprimento que a contagem final de todos os valores. Realizando uma soma cumulativa do rep vetor com o último elemento removido e 1 colocado no início, eu recebo um vetor de índices em index mostrando onde os grupos de valores replicados começarão. Esses pontos são marcados com outros. Quando uma soma cumulativa é realizada em index, Recebo um vetor de índice final que posso usar para indexar em v Para criar o vetor de valores replicados heterogeneamente.

Outras dicas

Para adicionar à lista de soluções possíveis, considere esta:

vv = cellfun(@(a,b)repmat(a,1,b), num2cell(v), num2cell(rep), 'UniformOutput',0);
vv = [vv{:}];

Isso é muito mais lento que o de gnovice..

O que você está tentando fazer é Decodificação do comprimento da execução. Um utilitário de alto nível confiável/vetorizado é o Submissão Fex rude():

% example inputs
counts = [2, 3, 1];
values = [24,3,30];

o resultado

rude(counts, values)
ans =
    24    24     3     3     3    30

Observe que esta função também executa a operação oposta, ou seja, codas de comprimento de corrida um vetor ou em outras palavras retorna values e o correspondente counts.

accumarray A função pode ser usada para fazer o código funcionar se os zeros sair rep variedade

function vv = repeatElements(v, rep)
index = accumarray(cumsum(rep)'+1, 1);
vv = v(cumsum(index(1:end-1))+1);
end

Isso funciona semelhante à solução do GNOVICE, exceto que os índices são acumulados sendo atribuídos a 1. Isso permite pular alguns índices (3 e 6 no exemplo abaixo) e remover os elementos correspondentes da saída.

>> v = [3 1 42 9 4 42];
>> rep = [2 3 0 1 5 0];
>> index = accumarray(cumsum(rep)'+1, 1)'

index =

     0     0     1     0     0     2     1     0     0     0     0     2

>> cumsum(index(1:end-1))+1

ans =

     1     1     2     2     2     4     5     5     5     5     5

>> vv = v(cumsum(index(1:end-1))+1)

vv =

     3     3     1     1     1     9     4     4     4     4     4
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top