Sliding window function over column vector, Help!

조회 수: 4 (최근 30일)
Thashen  Naidoo
Thashen Naidoo 2019년 11월 23일
답변: Thashen Naidoo 2019년 11월 24일
I have a dataset with months, location (xyz) and magnitude. There is no actual time values but it is ordered in time. I want to create a sliding window function over the column vector of magnitude to perform a calculation and store the output. The data is attached. The below code extracts data for month 7 which is July and plots a regression line for the data in the whole month. The total number of data points in July is 22708. How do I run a moving window of 500 points every one point (eg 1 to 500, 2 to 501, 3 to 502) over the dataset to get all the magnitudes for each window and then I will perform a calculation and store the output. eg 1 to 500 = b1, 2 to 501 = b2, 3 to 502=b3 etc, where b1,b2,b3 are the calculated results that must be stored in a vector.
%%extract data for a specific month
month7=month(month==7); %want to know how many values were taken at the 7th month
size7=size(month7);%get the size of the data set
value7=size7(1,1);%since matlab works in vectors, we only want the first row and fist column
M7=M(1:value7);%search for the magnitudes for that month
tbl7=tabulate(M7);
A7=tbl7(:,1:2);
Bfreq7=tbl7(:,2);
Bcumfreq7=cumsum(Bfreq7,1,'reverse');
Bmag7=tbl7(:,1);
Nlog7=log10(Bcumfreq7);
[p,S] = polyfit(Bmag7,Nlog7,1);
[y_fit,delta] = polyval(p,Bmag7,S);
plot(Bmag7,Nlog7,'bo')
hold on
plot(Bmag7,y_fit,'r-');
plot(Bmag7,y_fit+2*delta,'m--',Bmag7,y_fit-2*delta,'m--')
title('Linear Fit of Data with 95% Prediction Interv
I tried running a moving window function but it is not indexing the M7 values.
L=M7;
window=100;
for k1=1:L-window+1
datawin(k1,:)=k1:k1+window-1;
end
  댓글 수: 3
Thashen  Naidoo
Thashen Naidoo 2019년 11월 23일
Thank you so much. The data has months 7 to 10 and labelled them as M7, M8, M9, M10 to help me remember the months.
I want to perform two calculations to compare them, but I need help will getting the magnitudes in each respective window. The first calculation: b=loge/(M_ave - M_min), where e is the natural value (2.7), M_ave is the average magnitude for the window and M_min is the smallest magnitude for the window.
The second "calculation" that I will do for each window is perform a regression as I have done in the sample code with polyfit.
Thank you so much for your suggestion on the layout of the code.
Thashen  Naidoo
Thashen Naidoo 2019년 11월 23일
In terms of extracting the data, M is the magnitude which is recorded for July, Aug, Sept and October. Every M that is recorded for July has a value 7 attributed to it in another row. The same for August with a value 8 in another row etc. I basically indexed for the month == 7 to get the size of that and then extracted the magnitude values for that size in the column with magnitudes.

댓글을 달려면 로그인하십시오.

답변 (2개)

Guillaume
Guillaume 2019년 11월 24일
"The data has months 7 to 10 and labelled them as M7, M8, M9, M10 to help me remember the months."
Do not do that! Numbered variables are always a bad idea. Your numbered variables will force you to copy/paste your code for each month just to change the variable name. It will make everything more complicated, not simpler.
"Every M that is recorded for July has a value 7 attributed to it in another row. The same for August with a value 8 in another row etc. I basically indexed for the month == 7 to get the size of that and then extracted the magnitude values for that size in the column with magnitudes"
So you basically have a matrix with at least two columns with one column being the month and the other the magnitude. You may consider using a table for this as tables have plenty of features suited to this type of data. In particular, grouptransform would allow you to do your calculation for all the months at once.
Assuming that M is the magnitude column of your matrix and month the month column, your initial extraction of the values corresponding to a month does not work. Assuming that there are N rows corresponding to a month, your code is ignoring which actual rows these are and always extract the first N rows of the matrix. The proper code would be:
thismonthdata = M(month == 7);
I'm a bit confused by your equation "b=loge/(M_ave - M_min)", is by definition 1. I'm assuming your actual equation is , in which case it can be implemented very simply as
windowsize = 100
b = log(movmean(M, windowsize, 'EndPoints', 'discard') - movmean(M, windowsize, 'EndPoints', 'discard'));
There's no built-in function to perform your second calculation over a window, so you will have to use a loop. In that case, you may as well do the above in the loop as well, it would go like:
windowsize = 100;
for start = 1:numel(M)-windowsize+1
windowdata = M(start+(1:windowsize));
b = log(mean(windowdata) - min(windowdata)); %better variable name needed. I'm unclear what b is used for
frequency_table = tabulate(windowdata);
logcumulative_frequency = log10(cumsum(frequency_table(:, 3), 1, 'reverse'));
magnitude = frequency_table(:, 1);
[p, S] = polyfit(magnitude, logcumulative_frequency, 1);
[y_fit, delta] = polyval(p, magnitude, S);
%... store the results somewhere. I'm unclear what you want to do here.
end
  댓글 수: 1
Thashen  Naidoo
Thashen Naidoo 2019년 11월 24일
The month is a seperate vector which has (7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,9,9 etc) which all corresponds to data collected for the respective months. The entire length of the month vector is the same as the Magnitude vector. The data was recorded in order of time. So what I thought is that (for example, The first ten elements of M will correspond to the data recorded in July, then 7 events after correspond to events recorded in August etc). Thats what I applied to my data. Is that still incorrect?
The vectors are all column vectors. What I want to do is to look at the time variation of the data. I want to select events with a moving window of 500 (1 to 500, 2 to 501 ...till the end).
For each of those iterations, I want to use the tabulate function so that the first column will be magnitude and the second column will be frequency.
Then I want to take the log (base 10) of the frequency values and then get the cumulative frequencies. After that I want to plot a Magnitude vs Log cumulative frequency and plot a regression line to obtain the gradient value. I want to do that for each iteration and store all the gradient values in one vector, which I will plot. Will this be too tedious? How could I do that? month pic.JPG

댓글을 달려면 로그인하십시오.


Thashen  Naidoo
Thashen Naidoo 2019년 11월 24일
windowsize=500;
N=numel(M)/windowsize;
for i=1:N
for j=1:windowsize
frequency_table=tabulate(j);
logcumulative_frequency=log10(cumsum(frequency_table(:,2),1,'reverse'));
magnitude=frequency_table(:,1);
p=polyfit(magnitude,logcumulative_frequency,1);
slope=p(1);
end
V(i)=slope
end
I tried the above but its not working.

카테고리

Help CenterFile Exchange에서 Time Series에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by