2

Matlab には、次のようなベクトルがあります。

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

今やりたいことは、このベクトルの 1 の数を数えることです。連続した 1 は 1 としてカウントされます。さらに、1 の間の 0 の平均数と中央値も計算したいと考えています。したがって、この例では:

1秒:5

中央値 0: 3.5

平均 0: 3

ループ内の各要素を調査し、前の要素と次の要素をチェックするブルート フォース メソッドでそれを解決しました。しかし、もっと速い解決策が必要だと確信しています。何か案が?

4

3 に答える 3

3

vector のデータが与えられるとv

v = [ 0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1 ]; % data

次のように計算します。

w = [ 1 v 1 ]; % auxiliary vector
runs_zeros = find(diff(w)==1)-find(diff(w)==-1); % lenghts of runs of 0's

% Desired results:
number_ones = length(runs_zeros)-1+v(1)+v(end);
% For average and median, don't count first run if v(1) is 0,
% or last run if v(end) is 0:
average_runs_zeros = mean(runs_zeros(2-v(1):end-1+v(end))); 
median_runs_zeros = median(runs_zeros(2-v(1):end-1+v(end)));

これは、文字列への変換を必要としないため、@TryHard のソリューションよりも高速です。

于 2013-09-08T14:23:32.243 に答える
1

さて、これはうまくいっているようです

>> a=[0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1];
>> %Remove traling and leading zeros
>> y = a(find(a,1,'first'):find(a,1,'last'));
>> q = diff([0 a 0] == 1);
>> v = find(q == -1) - find(q == 1);
>> length(v) % Consecutive Ones
ans =

     5

>> q = diff([0 ~y 0] == 1);
>> v = find(q == -1) - find(q == 1);
>> v

v =

     3     4     4     1

>> median(v)

ans =

    3.5000

>> mean(v)

ans =

    3
于 2013-09-08T13:54:13.020 に答える