Frage

Diese Frage hat hier bereits eine Antwort:

Meine Frage ähnelt diesem eines, aber ich möchte jedes Element gemäß einer Anzahl in einem zweiten Array derselben Größe replizieren.

Ein Beispiel dafür, sagen ich, ich hatte ein Array v = [3 1 9 4], Ich möchte benutzen rep = [2 3 1 5] um das erste Element 2 Mal, das zweite dreimal und so weiter zu replizieren, um zu bekommen [3 3 1 1 1 9 4 4 4 4 4].

Bisher benutze ich eine einfache Schleife, um die Arbeit zu erledigen. Das habe ich angefangen:

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

Ich habe es geschafft, durch Vorab -Raum zu verbessern:

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

Ich habe jedoch immer noch das Gefühl, dass es eine klugere Möglichkeit geben muss, dies zu tun ... danke

War es hilfreich?

Lösung

Hier ist eine Möglichkeit, dies zu erreichen:

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

Dies funktioniert, indem zuerst ein Indexvektor von Nullen die gleiche Länge wie die endgültige Anzahl aller Werte erstellt. Durch Durchführung einer kumulativen Summe der rep Vektor mit dem letzten entfernten Element und einer zu Beginn platzierten 1 bekomme ich einen Vektor von Indizes in index zeigen, wo die Gruppen der replizierten Werte beginnen. Diese Punkte sind mit denen gekennzeichnet. Wenn eine kumulative Summe durchgeführt wird index, Ich bekomme einen endgültigen Indexvektor, in den ich indexieren kann v Erstellen Sie den Vektor heterogen-replikierter Werte.

Andere Tipps

Um die Liste der möglichen Lösungen hinzuzufügen, sollten Sie Folgendes berücksichtigen:

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

Dies ist viel langsamer als die von Gnovice..

Was Sie versuchen zu tun, ist Läufe Decode. Ein hoher zuverlässiger/vektorisierter Versorgungsunternehmen ist das FEX -Einreichung rude():

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

das Ergebnis

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

Beachten Sie, dass diese Funktion auch die entgegengesetzte Operation ausführt, dh auch die entgegengesetzte Operation Langlängen-Codes Ein Vektor oder mit anderen Worten kehrt zurück values und das entsprechende counts.

accumarray Funktion kann verwendet werden, um den Code funktionieren zu rep Array

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

Dies funktioniert ähnlich wie die Lösung von Gnovice, mit der Ausnahme, dass Indizes stattdessen zugewiesen werden. Dies ermöglicht es, einige Indizes (3 und 6 im folgenden Beispiel) zu überspringen und entsprechende Elemente aus der Ausgabe zu entfernen.

>> 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top