choose n elements from array and increase sequentially
조회 수: 16 (최근 30일)
이전 댓글 표시
I have a 1x100 matrix with its values varying from 0-50. I have to take 1st to 10th elements,check how many samples have values between 20-30, display the answer. then I have to take elements from 2nd to 11th (next 10 samples),check how any samples have values between 20-30. then take samples from 3 to 12 and continue so on.
How can I implement this?
댓글 수: 2
Rik
2018년 3월 26일
What have you tried so far? It seems like a for-loop would work (even if that probably isn't the fastest solution).
답변 (2개)
John D'Errico
2018년 3월 26일
편집: John D'Errico
2018년 3월 26일
Problems like this are always solvable in many ways. Easy to write is not always efficient. And there are often tradeoffs due to memory considerations. A vectorized solution might require a huge amount of memory if the vector is long.
Thus, suppose you have N elements in the vector, and a sliding window length of size W. So consider a vector V, of length 25:
V = round(rand(1,25)*50)
V =
4 17 35 45 18 12 37 3 49 42 25 16 44 9 9 0 26 41 21 12 35 17 5 13 29
Assume a sliding window length of 10.
N = length(V);
W = 10;
Vlims = [20,30];
Solution 1: A loop. Easy to write. I'm not gonna bother, because there are better ways to invest my time.
Solution 2: Replicate your vector into a matrix, of size W by N-W+1. So column 1 will be elements 1:W. Column 2 will be elements 2:(W+1), etc. Then you just count how many elements fall in the interval in each row. Easy to write this code, although you would need to build that matrix.
M = V((0:W-1)' + (1:N-W+1));
slidingcount = sum((M >= Vlims(1)) & (M<= Vlims(2)),1)
slidingcount =
0 1 1 1 1 1 1 2 2 3 3 2 2 2 2 3
The disadvantage of solution 2 is the amount of memory required if N or W are too large.
Solution 3: Like solution 2, but replicate only a boolean vector, which indicates whether a given element is in the interval of interest.
B = (V >= Vlims(1)) & (V<= Vlims(2));
slidingcount = sum(B((0:W-1)' + (1:N-W+1)),1)
slidingcount =
0 1 1 1 1 1 1 2 2 3 3 2 2 2 2 3
Thus, solution 3 works the same as solution 2, but uses considerably less memory, since the vector elements themselves were not replicated, but only a vector of booleans, so a logical vector.
Solution 4: Use conv to perform the summation implicitly. No array ever gets generated.
B = (V >= Vlims(1)) & (V<= Vlims(2));
slidingcount = conv(double(B),ones(1,W),'valid')
slidingcount =
0 1 1 1 1 1 1 2 2 3 3 2 2 2 2 3
So a good trick to remember is anytime you have a function that needs a sum over a sliding window, conv may be there to solve your problem.
댓글 수: 0
David Fletcher
2018년 3월 26일
편집: David Fletcher
2018년 3월 26일
dummyMatrix=randi(50,1,100)
result=zeros(1,91)
for iter=1:91
%extract 10 element window
extract=dummyMatrix(iter:9+iter)
%count elements that meet the condition
results(iter)=sum((extract>=20)&(extract<=30))
end
I assume you stop gathering the counts at element 91 (since the window will then be element 91 through to element 100)
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Data Distribution Plots에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!