Reputation: 167
I have two vectors in MATLAB as follows:
Crossing Time = [11 14 16 18 29 18 53 22 18 11 19 10 15 15 13 18];
Count = [0 0 2 3 0 0 4 3 6 2 5 0 3 5 2 7];
I want to calculate mean of crossing time based on the count. For example: If count is zero, corresponding crossing time is just the value from the crossing time vector i.e. for first zero in count vector, crossing time is 11 and for second zero the crossing time is 14. This is straightforward. However, if the count is non-zero, such as 2 (third column in count vector), I want the mean of 2nd and 3rd columns of crossing time vector beside 2 (i.e. mean of 14 and 16 beside 2). If the count is 4 (7th column in count vector) then I want the mean of 4th to 7th columns of the crossing time vector.
In doing that I would have the following mean vector:
Mean = [11 14 15 16 29 18 29.5 31 26.33 14.5 24.6 10 14.67 14 14 14.43]
How can I do this in a loop so that I can repeat this for my huge vectors with 90,000 records. It should be straightforward for any programmer but unfortunately I have very limited programming knowledge.
Thanks for your help.
Upvotes: 1
Views: 61
Reputation: 25232
Assuming there is no Count = 1
but Count = 0
behaves like Count = 1
,
Count(~Count) = 1;
cs = [0 cumsum(CrossingTime)];
meanVal = arrayfun(@(x,y) (cs(x+1) - cs(1 + x-y))/y, 1:numel(Count), Count)
The loop could be as follows:
Count(~Count) = 1
meanVal = zeros(1,numel(CrossingTime));
for ii = 1:numel(CrossingTime)
meanVal(ii) = mean( CrossingTime(ii:-1:ii-Count(ii)+1));
end
Alternatively use arrayfun
, which is basically the same:
Count(~Count) = 1
meanVal = arrayfun(@(x) mean( CrossingTime(x:-1:x-Count(x)+1)), 1:numel(Count))
Upvotes: 0
Reputation: 4549
@thewaywewalk gave a nice answer. Just for the record, here is a modified version which precomputes the sums to run faster:
cumulative = [0 cumsum(CrossingTime)];
meanVal = arrayfun(@(x) (cumulative(x + 1) - cumulative(x - max(Count(x), 1) + 1)) / max(Count(x), 1), 1:numel(Count));
clear cumulative;
Running times with a randomized 90.000 array (as mentioned on the question):
NOTE: The array was created using this:
N = 90000;
CrossingTime = randi(10000, 1, N);
Count = min(0:N-1, randi(N, 1, N) - 1);
Upvotes: 1