8

行列がありAます。ここで、5より大きい要素の数とそれに対応するインデックスを見つけたいと思います。forループを使用せずにmatlabでこれを解決するにはどうすればよいですか?

たとえば、次の場合A = [1 4 6 8 9 5 6 8 9]'

  • 要素数>5:6
  • インデックス:[3 4 5 7 8 9]
4

3 に答える 3

14

あなたが使用するfind

index = find(A>5);
numberOfElements = length(index);
于 2012-10-05T00:29:26.930 に答える
4

を使用する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
于 2012-10-05T05:44:15.150 に答える
2

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つのオプションがあります。

  • matlabは、インデックス呼び出しの前に、doubleインデックスをuint32インデックスに明示的に変換します(整数テストで行うのと同じように)
  • matlabはdoubleを渡し、インデックス呼び出し中にその場でdouble->intキャストを実行します

2番目のオプションは、doubleインデックスを1回読み取るだけでよいため、より高速になるはずです。明示的な変換テストでは、doubleインデックスを読み取り、整数インデックスを書き込み、実際のインデックス作成中に整数インデックスを再度読み取る必要があります。だからmatlabはもっと速いはずです...なぜそうではないのですか?

于 2012-10-05T10:41:37.503 に答える