2016-02-22 9 views
6

Y = zeros(5000,10); yは、1から10までの数字からなる5000 x 1の定義済みベクトルです。このMATLABコードを実装するより良い方法はありますか?

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

私のコードの残りの部分がベクトル化され、あなたがbsxfunを使用することができますループ

+2

あなたが内部本当にささいなことをやっているので、このコードは、おそらくそれがあるとして、非常に高速である:列インデックス、その後、必要に応じてfullに変換するように。 –

答えて

6

のためのいずれかを含んでいないので、これを実装するより良いと簡単な方法があります:

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

の代わりにあなたのコードでは、y(i)==[1:10]を使って各行を作成することができ、最終的にベクトル化するためにbsxfunにラップされます。

もう一つのアイデアは、指数計算のようになります。

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

ニースキャッチ@ダニエル。しかし、返された行列は、たとえあなたが 'zeros()'をあらかじめ割り当てていても論理的です。 'double()'変換が必要な場合があります。 – Alessiox

+0

私のシステムでは、これは 'for'ループより遅いです...(変換あり) – zeeMonkeez

+0

私には、' double() '変換を含む' bsxfun() 'は、 'for 'ループ(0.002190s対0.005001s) – Alessiox

2

あなたはsub2indを使用することができます。

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

しかし、これは実際には少し遅いかもしれません:

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

ここでは別のアプローチがあります:を使用してsparse行列を作成する

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