2014-04-15 4 views
5

Ich versuche, den folgenden MATLAB Betrieb vektorisieren:Erstellen Sie einen Null-gefüllten 2D-Array mit Einsen an durch einen Vektor indiziert Positionen

ein Spaltenvektor mit Indexen, ich mag eine Matrix mit dem gleichen Anzahl der Zeilen der Spalte und eine feste Anzahl von Spalten. Die Matrix wird mit Nullen initialisiert und enthält Einsen in den von den Indizes angegebenen Positionen . Hier

ist ein Beispiel für das Skript, das ich schon geschrieben habe:

y = [1; 3; 2; 1; 3]; 
m = size(y, 1); 

% For loop 
yvec = zeros(m, 3); 
for i=1:m 
    yvec(i, y(i)) = 1; 
end 

Das gewünschte Ergebnis ist:

yvec = 

1  0  0 
0  0  1 
0  1  0 
1  0  0 
0  0  1 

Ist es möglich, das gleiche Ergebnis ohne die for-Schleife zu erreichen ? Ich habe versucht, etwas wie folgt:

% Vectorization (?) 
yvec2 = zeros(m, 3); 
yvec2(:, y(:)) = 1; 

aber es funktioniert nicht.

Antwort

5

Zwei Ansätze, die Sie hier verwenden können.

Ansatz 1:

y = [1; 3; 2; 1; 3]; 
yvec = zeros(numel(y),3); 
yvec(sub2ind(size(yvec),1:numel(y),y'))=1 

Ansatz 2 (One-Liner):

yvec = bsxfun(@eq, 1:3,y) 
+0

Besonders gefällt mir der zweite Ansatz :) – Muffo

+3

Auch erscheint es 'yvec' hat Anzahl der Spalten gleich dem Maximum von 'Y', so dass für die zweiten Ansatz können Sie eine verallgemeinerte Version als 'yvec = bsxfun (@eq, 1: max (y), y)' haben. – Divakar

+0

Oder, nur in der Oktave, '(1: 3) == y', was Approach 2 mit [Broadcasting] ist (https://www.gnu.org/software/octave/doc/v4.0.1/Broadcasting.html) . – ederag

4

Noch ein anderer Ansatz:

yvec = full(sparse(1:numel(y),y,1)); 
+0

Ich kannte die spärliche Darstellung in Matlab nicht, aber es scheint in diesem Fall wirklich nützlich zu sein! – Muffo

+1

Illustrativ, danke! – KAs

3

Sie können dies tun, mit accumarray :

yvec = accumarray([(1:numel(y)).' y], 1); 
0

ich es auf diese Weise tat:

classes_count = 10; 
sample_count = 20; 
y = randi([1 classes_count], 1, sample_count); 

y_onehot = zeros(classes_count, size(y, 2)); 
idx = sub2ind(size(y_onehot), y, [1:size(y, 2)]); 
y_onehot(idx) = 1 
Verwandte Themen