Is there a way to average sequential data on an array and then be able to split the array?
2 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I want to be able to split an array of n rows and 5 columns into sections every time the data of a specific column (let's call it column3) crosses zero, and every time there is a peak or valley. I want the split of the array to happen to all the data (the conditions are based on column3, but are applied to all the columns).
The data also has repeated values for the whole data set; for those values I want to average the data of each column by considering the data that was averaged for a specific column per section.
if true
%code example
column3 = [-6 -6 -6 -6 -5 -5 -3 -3 -3 -1 -1 -1 0 0 2 2 2 3 3 5 5 5 5 6 6 6 6 4 4 4 3 3 3 3 3 3 3 2 2 2 1 1 1 1 0 0 -1 -1 -2 -3 -5 -5 -5 -5 -5 -5 -5 -6 -6 -6];
end
I want this to end up looking like
if true
%code result
column3_1 = [-6 -5 -3 -1 0]
column3_2 = [0 2 3 5 6]
column3_3 = [6 4 3 2 1 0]
column3_4 = [0 -1 -5 -3 -5 -6]
end
Then these changes should be also applied to the other columns based on the rows that were averaged for column3.
-----
My line of thought is first I must apply a code to average all the values that are repeated and in sequence using a loop, then separate the sections based on peaks, valleys, and crossing zeroes.
if true
% code thought process
%first average all values
column3_avg = [-6 -5 -3 -1 -0 2 3 5 6 4 3 2 1 0 -1 -2 -3 -5 -6]
%then divide into sections
column3_1 = [-6 -5 -3 -1 0]
column3_2 = [0 2 3 5 6]
column3_3 = [6 4 3 2 1 0]
column3_4 = [0 -1 -5 -3 -5 -6]
end
The main issue is that I can't seem to average only equal sequential data. Is there an effective way to do this on Matlab with a loop or am I better off doing it all by hand?
Thank you in advance
0 comentarios
Respuesta aceptada
Guillaume
el 17 de Ag. de 2017
Editada: Guillaume
el 17 de Ag. de 2017
The modern and easy way to do what you want is certainly not by hand, and not with a loop either:
demomatrix = rand(60, 10);
demomatrix(:, 3) = [-6 -6 -6 -6 -5 -5 -3 -3 -3 -1 -1 -1 0 0 2 2 2 3 3 5 5 5 5 6 6 6 6 4 4 4 3 3 3 3 3 3 3 2 2 2 1 1 1 1 0 0 -1 -1 -2 -3 -5 -5 -5 -5 -5 -5 -5 -6 -6 -6];
%averaging of identical consecutive values:
groupids = cumsum([1; diff(demomatrix(:, 3))~=0]);
averagedmatrix = splitapply(@(rows) mean(rows, 1), demomatrix, groupids)
%splitting at 0 and direction reversal:
groupids = cumsum([false; diff(sign(diff(averagedmatrix(:, 3))))~=0; false] ...identify change of direction
| averagedmatrix(:, 3) == 0) + 1; %identify zeros
splitaverage = splitapply(@(rows) {rows}, averagedmatrix, groupids);
Now, you want the transition point to belong to both side. A bit unusual, but can be adjusted after the fact, with a loop indeed:
for row = 1:numel(splitaverage)-1
splitaverage{row}(end+1, :) = splitaverage{row+1}(1, :);
end
celldisp(splitaverage)
Note that the result is stored in a cell array. Do not create separate variables for it, use indexing. Instead of your colum3_4, use
splitaverage{4}
Más respuestas (1)
Aveek Podder
el 17 de Ag. de 2017
Hopefully this solves the problem. The Cell type variable ‘sections’ contains the split data and ‘column3’ contains the column data.
if true
% code
column3 = [-6 -6 -6 -6 -5 -5 -3 -3 -3 -1 -1 -1 0 0 2 2 2 3 3 5 5 5 5 6 ...
6 6 6 4 4 4 3 3 3 3 3 3 3 2 2 2 1 1 1 1 0 0 -1 -1 -2 -3 -5 -5 -5 ...
-5 -5 -5 -5 -6 -6 -6];
% First the Average part is done
column3_avg = column3([1,diff(column3)]~=0);
% Dividing it into Sections
diff_col = [0,diff(column3_avg)];
strt_pnt = 1;
sections = cell(0);
for i = 1:length(column3_avg)
end_pnt = i;
if i == length(column3_avg)
sections{length(sections)+1} = column3_avg(strt_pnt:end_pnt);
break;
end
if column3_avg(i) == 0 || (diff_col(i)*diff_col(i+1) < 0)
sections{length(sections)+1} = column3_avg(strt_pnt:end_pnt);
strt_pnt = i;
end
end
% Accessing the data
num_of_sections = length(sections)
column3_1 = sections{1}
column3_2 = sections{2}
column3_4 = sections{4}
end
7 comentarios
Guillaume
el 17 de Ag. de 2017
Editada: Guillaume
el 17 de Ag. de 2017
The harm is that John usurped the authority of the original questioner. It is up to the original poster to decide which solution is best (I happen to think mine is better).
Certainly, not John, and certainly not for the reason stated.
The reputation points are irrelevant. The principle is.
As as been discussed before, accepting an answer does not just give reputation points, it also puts the accepted answer in a lot more prominence.
Ver también
Categorías
Más información sobre Whos en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!