行列がありA
ます。ここで、5より大きい要素の数とそれに対応するインデックスを見つけたいと思います。forループを使用せずにmatlabでこれを解決するにはどうすればよいですか?
たとえば、次の場合A = [1 4 6 8 9 5 6 8 9]'
:
- 要素数>5:6
- インデックス:
[3 4 5 7 8 9]
あなたが使用するfind
:
index = find(A>5);
numberOfElements = length(index);
を使用するsum
と、1つのコマンドで要素の数を取得できます。
numberOfElements = sum(A>5);
本当に明示的なインデックスが必要ですか?論理行列A>5
はインデックスとしても使用できるため(通常、を使用したインデックス作成よりも少し効率的ですfind
):
index = (A>5);
numberOfElements = sum(index);
完全を期すために:論理による索引付けは、通常の索引付けと同じです。
>> A(A>5)
ans =
6 8 9 6 8 9
Rodyとの上記の議論に動機付けられて、MATLABで整数と論理配列のインデックス付けの速度をテストする簡単なベンチマークがあります。「ベクトル化された」MATLABは主にインデックス付けに関するものなので、非常に重要なことです。それで
% random data
a = rand(10^7, 1);
% threashold - how much data meets the a>threashold criterion
% This determines the total indexing time - the more data we extract from a,
% the longer it takes.
% In this example - small threashold meaning most data in a
% will meet the criterion.
threashold = 0.08;
% prepare logical and integer indices (note the uint32 cast)
index_logical = a>threashold;
index_integer = uint32(find(index_logical));
% logical indexing of a
tic
for i=1:10
b = a(index_logical);
end
toc
% integer indexing of a
tic
for i=1:10
b = a(index_integer);
end
toc
私のコンピューターでは、結果は次のとおりです。
Elapsed time is 0.755399 seconds.
Elapsed time is 0.728462 seconds.
つまり、2つの方法はほぼ同じように実行されます。これが、私が例を選択した方法threashold
です。index_integer
配列がほぼ4倍大きいので、それは興味深いです!
index_integer 9198678x1 36794712 uint32
index_logical 10000000x1 10000000 logical
threashold
整数の値が大きいほど、インデックス作成が高速になります。の結果threashold=0.5
:
Elapsed time is 0.687044 seconds. (logical)
Elapsed time is 0.296044 seconds. (integer)
ここで何か間違ったことをしているのでない限り、整数インデックスはほとんどの場合最速のようです。
ただし、テストにインデックスの作成を含めると、結果は大きく異なります。
a = rand(1e7, 1);
threshold = 0.5;
% logical
tic
for i=1:10
inds = a>threshold;
b = a(inds);
end
toc
% double
tic
for i=1:10
inds = find(a>threshold);
b = a(inds);
end
toc
% integer
tic
for i=1:10
inds = uint32(find(a>threshold));
b = a(inds);
end
toc
結果(ロディ):
Elapsed time is 1.945478 seconds. (logical)
Elapsed time is 3.233831 seconds. (double)
Elapsed time is 3.508009 seconds. (integer)
結果(獲得者):
Elapsed time is 1.440018 seconds. (logical)
Elapsed time is 1.851225 seconds. (double)
Elapsed time is 1.726806 seconds. (integer)
したがって、整数を使用してインデックスを作成する場合、実際のインデックス作成は高速であるように見えますが、前後の論理インデックス作成の方がはるかに優れています。
ただし、最後の2つのメソッドの実行時の違いは予想外です。つまり、Matlabの内部は、実際のインデックス作成を行う前に各要素でエラーチェックを実行するために、doubleを整数にキャストしないようです。そうでなければ、doubleメソッドとintegerメソッドの間に実質的な違いは見られなかったでしょう。
編集私が見ているように、2つのオプションがあります。
2番目のオプションは、doubleインデックスを1回読み取るだけでよいため、より高速になるはずです。明示的な変換テストでは、doubleインデックスを読み取り、整数インデックスを書き込み、実際のインデックス作成中に整数インデックスを再度読み取る必要があります。だからmatlabはもっと速いはずです...なぜそうではないのですか?