Is there a way to average sequential data on an array and then be able to split the array?

2 visualizzazioni (ultimi 30 giorni)
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

Risposta accettata

Guillaume
Guillaume il 17 Ago 2017
Modificato: Guillaume il 17 Ago 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}

Più risposte (1)

Aveek Podder
Aveek Podder il 17 Ago 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 Commenti
Guillaume
Guillaume il 17 Ago 2017
Modificato: Guillaume il 17 Ago 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.
yz
yz il 17 Ago 2017
Thank you Guillaume. I feel your answer better suits my original question. I highly appreciate the addition of the other columns so I could better understand what is happening with the code.
I do not appreciate someone accepting an answer on my behalf, especially when I hadn't even had a chance to look at the answers. 7 hours ago I was asleep. While I appreciate John's readiness to evaluate the answers, I feel the poster should be given at least a day to compare answers and see how well they work for their purposes.
I do want to thank both Aveek and Guillaume for answering. I do really appreciate it.
Thank you,
- yz

Accedi per commentare.

Community Treasure Hunt

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

Start Hunting!

Translated by