2016-02-22 23 views
6

Y = zeros(5000,10); y ist ein 5000 x 1 vordefinierter Vektor bestehend aus Zahlen von 1 bis 10;Gibt es eine bessere Möglichkeit, diesen MATLAB-Code zu implementieren?

for i= 1:size(Y,1) 
    Y(i,y(i)) = 1; 
end 

Gibt es einen besseren und einfacheren Weg, dies zu implementieren, da der Rest meines Code vektorisiert ist und enthält keine für Schleife

+2

Dieser Code wahrscheinlich ziemlich schnell, wie es ist, weil Sie wirklich kleine Dinge innen tun. –

Antwort

6

könnten Sie bsxfun verwenden:

bsxfun(@eq,y,[1:10]) 

statt Ihr Code, Sie können jede Zeile mit y(i)==[1:10] erstellen, die schließlich in bsxfun eingepackt wird, um zu vektorisieren.

Eine weitere Idee wäre Indexberechnung sein:

Y((y-1).*5000+(1:5000).')=1; 
+2

Netter Fang @Daniel. Die zurückgegebene Matrix scheint jedoch logisch zu sein, auch wenn Sie sie mit 'Nullen()' vorbelegen. Eine 'double()' Konvertierung könnte erforderlich sein. – Alessiox

+0

Und auf meinem System ist dies Art und Weise langsamer als die 'for' Schleife ... (mit Umrechnung) – zeeMonkeez

+0

mir, die' bsxfun() ', einschließlich der' double() 'Umwandlung, nimmt die Hälfte der Zeit in Bezug auf die 'for' Schleife (0,002190s vs 0,005001s) – Alessiox

2

Sie sub2ind verwenden:

Y(sub2ind(size(Y), 1:size(Y, 1), y')) = 1; 

Allerdings könnte dies tatsächlich etwas langsamer:

Y = zeros(5000,10); 
y = randi(10, 5000, 1); 

tic 
for jj = 1:1000 
    for i = 1:size(Y,1) 
     Y(i,y(i)) = 1; 
    end 
end 
toc 
% Elapsed time is 0.126774 seconds. 

tic 
for jj = 1:1000 
    Y(sub2ind(size(Y), 1:size(Y, 1), y')) = 1; 
end 
toc 
% Elapsed time is 0.139531 seconds. 

% @Daniel's solution 
tic 
for jj = 1:1000 
    Y = double(bsxfun(@eq, y, 1:10)); 
end 
toc 
%Elapsed time is 0.187331 seconds. 
2

Hier ist ein weiterer Ansatz: Erstellen Sie eine sparse Matrix mit y als Spaltenindizes, und dann zu full konvertieren, wenn nötig:

Y = full(sparse(1:numel(y), y, 1, numel(y), 10)); 
Verwandte Themen