Elementweise Array-Replikation in Matlab
-
21-09-2019 - |
Frage
Lassen Sie uns sagen, ich habe ein eindimensionales Array:
a = [1, 2, 3];
Sie haben einen eingebauten in Matlab-Funktion, die eine Anordnung und eine ganze Zahl n
nimmt und repliziert jeweils
Element des Arrays n mal?
Zum Beispiel replicate(a, 3)
Aufruf sollte [1,1,1,2,2,2,3,3,3]
zurück.
Beachten Sie, dass dies gar nicht so repmat
gleich ist. Ich kann sicherlich replicate
implementieren, indem für jedes Element zu tun repmat
und verketten das Ergebnis, aber ich frage mich, ob es eine eingebaute Funktion, die effizienter ist.
Lösung
Ab R2015a , gibt es eine gebaut -in und dokumentierte Funktion, dies zu tun, repelem
:
repelem
Replizieren Elemente eines Arrays.
W = repelem(V,N)
, mit VektorV
und SkalareN
, erzeugt einen VektorW
wobei jedes Element vonV
N
mal wiederholt wird.
Das zweite Argument kann auch ein Vektor, der die gleichen Länge wie V
sein, die Anzahl von Wiederholungen für jedes Element zu spezifizieren. Für 2D-Replikation:
B = repelem(A,N1,N2)
Keine Notwendigkeit für kron
oder andere Tricks mehr!
UPDATE: Für einen Leistungsvergleich mit anderen schnellen Methoden finden Sie in der Q & A Wiederholen Sie Kopien von Array-Elementen . Lauflänge in MATLAB Decodierung
Andere Tipps
Ich bin ein Fan von der KRON Funktion:
>> a = 1:3;
>> N = 3;
>> b = kron(a,ones(1,N))
b =
1 1 1 2 2 2 3 3 3
Sie können unter auch einen Blick diese damit verbundene Frage (die mit replizierenden Elementen von 2-D-Matrizen behandelt), um einige der anderen Lösungen zu sehen Einbeziehung Matrix Indizierung. Hier ist eine solche Lösung (inspiriert von Edrics Antwort ):
>> 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
Einige exotische Alternativen. Zugegeben mehr lustig als nützlich:
-
Weisen Sie das (erste) Ergebnis
meshgrid
auf einen Vektor:b = NaN(1,numel(a)*n); %// pre-shape result b(:) = meshgrid(a,1:n);
-
Erstellen Sie eine Matrix, die durch
a
multipliziert ergibt das Ergebnis:b = a * fliplr(sortrows(repmat(eye(numel(a)),n,1))).';
-
Verwenden
ind2sub
die Indizes zu generieren:[~, ind] = ind2sub([n 1],1:numel(a)*n); b = a(ind);
Wenn Sie die Bildverarbeitung Toolbox haben, gibt es eine weitere Alternative:
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));