Question

    

Cette question a déjà une réponse ici:

         

Ma question est similaire à ce , mais je voudrais reproduire chaque élément en fonction d'un nombre spécifié dans une deuxième matrice de la même taille.

Un exemple de cela, que j'ai eu un v = [3 1 9 4] tableau, je veux utiliser rep = [2 3 1 5] pour reproduire le premier élément 2 fois, trois fois deuxième, et ainsi de suite pour obtenir [3 3 1 1 1 9 4 4 4 4 4].

Jusqu'à présent, je suis en utilisant une simple boucle pour faire le travail. C'est ce que j'ai commencé avec:

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

J'ai réussi à améliorer par préallocation espace:

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

Cependant, je pense toujours qu'il doit y avoir un moyen plus intelligent de faire ça ... Merci

Était-ce utile?

La solution

Voici une façon que j'aime accomplir ceci:

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

Cela fonctionne en créant d'abord un vecteur d'indices de zéros de la même longueur que le décompte final de toutes les valeurs. En effectuant une somme cumulative du vecteur rep avec le dernier élément enlevé et 1 placé au début, je reçois un vecteur d'indices en index montrant où les groupes de valeurs répliquées commenceront. Ces points sont marqués par les. Lorsqu'une somme cumulée est effectuée sur index, je reçois un vecteur d'indice final que je peux utiliser pour indexer v pour créer le vecteur des valeurs répliquées de manière hétérogène.

Autres conseils

Pour ajouter à la liste des solutions possibles, considérer celle-ci:

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

Ceci est beaucoup plus lent que celui par gnovice ..

Qu'est-ce que vous essayez de faire est de decode-RLL . Un utilitaire fiable / vectorisée de haut niveau est le FEX soumission rude() :

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

le résultat

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

Notez que cette fonction effectue l'opération inverse, ainsi, à savoir encode de longueur de suite un vecteur ou en d'autres termes renvoie values et le counts correspondant.

fonction accumarray peut être utilisée pour faire fonctionner le code si des zéros sortie dans le tableau de rep

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

fonctionne de manière similaire à la solution de gnovice, sauf que les indices sont accumulés au lieu d'être affecté à 1. Ceci permet d'ignorer certains indices (3 et 6 dans l'exemple ci-dessous) et supprimer des éléments correspondants à partir de la sortie.

>> 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top