How can I find the average of Y values for a given X?
12 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Juan Fiscina
am 11 Aug. 2016
Kommentiert: Juan Fiscina
am 11 Aug. 2016
Ok, so I have 2 vectors: V for Velocity and F for Force. For each Velocity value, there are several values of Force, for which I want to find the average. It might be worth noting that the Velocity vector is not ordered or a line, but a sinusoidal. What I mean by this is that the velocity oscillates from X to -X several cycles, so there are multiple velocity=x values.
The commands that I need are quite specific: I basically need a function/loop/whatever that will get the velocity value 1, then see how many values of force apply for it, then calculate the average of those force values. Next it gets the velocity value of 2 and average all the force values for v=2, etc.
Thanks in advance and please let me know if you require further detail! :)
0 Kommentare
Akzeptierte Antwort
Azzi Abdelmalek
am 11 Aug. 2016
Bearbeitet: Azzi Abdelmalek
am 11 Aug. 2016
Look at this example
M=randi(10,100,2) % First column is velocity varying from 1 to 10, the second is Force
[V,jj,kk]=unique(M(:,1)) % Unique values of V
mean_F=accumarray(kk,(1:numel(kk))',[],@(x) mean(M(x,2))) % mean of F
out=[V,mean_F]
3 Kommentare
Azzi Abdelmalek
am 11 Aug. 2016
Look at this small example
M=[1 10;1 20;1 30;2 50; 2 70]
M =
1 10
1 20
1 30
2 50
2 70
[V,jj,kk]=unique(M(:,1)) % Unique values of V
V =
1
2
jj =
1
4
kk =
1
1
1
2
2
mean_F=accumarray(kk,(1:numel(kk))',[],@(x) mean(M(x,2))) % mean of F
mean_F =
20
60
you need to read the documentation of accumarray
Weitere Antworten (2)
Peter Perkins
am 11 Aug. 2016
Two other possibilities that are very simple, using Azzi's example:
1) If you have R2013b or later,
>> M = randi(10,100,2); % First column is velocity varying from 1 to 10, the second is Force
>> t = array2table(M,'VariableNames',{'Velocity' 'Force'});
>> varfun(@mean,t,'GroupingVariable','Velocity')
ans =
Velocity GroupCount mean_Force
________ __________ __________
1 11 5.5455
2 11 3.8182
3 9 4.7778
4 4 4
5 9 4.6667
6 13 5.7692
7 12 4.25
8 6 6.5
9 14 4.5714
10 11 6.2727
2) If you are using R2016a or later,
>> g = findgroups(M(:,1));
>> splitapply(@mean,M(:,2),g)
ans =
5.5455
3.8182
4.7778
4
4.6667
5.7692
4.25
6.5
4.5714
6.2727
0 Kommentare
John D'Errico
am 11 Aug. 2016
Too late for you to accept or not, but as an alternative for others who might chance upon this question, is my consolidator tool, as found on the file exchange.
It solves exactly the question that you ask, returning a single set of x values that are now all unique, with the average y at that value x. Or in your case, it will reduce the F vector, by averaging, looking for replicates at each V in the vector.
Note there is a serious issue you will need to recognize, IF your vector V is in the form of floating point numbers. So if the vector V here is composed of only nice simple integers, then the accumarray trick works well. If not, then you need some sort of a tolerance. In that case, consolidator allows you to collect those points that are near each other.
Finally, you might decide to use a binning technique. In that case, you might pick bins, such that ever point that lies in exactly one of a set of intervals. So you might use break points like this
Vbreaks = linspace(min(V),max(V),20);
then you would use a tool to determine which bin every value of V falls in. The function histc (now replaced by histcounts) does this. At then end, accumarray would again be a good tool to take the averages within each set of bins. (Be careful though, as if any bin had no points that fell into it, this scheme would yield zero for that bin as the average.)
Siehe auch
Kategorien
Mehr zu Operators and Elementary Operations finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!