How can I find the average of Y values for a given X?
16 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Juan Fiscina
el 11 de Ag. de 2016
Comentada: Juan Fiscina
el 11 de Ag. de 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 comentarios
Respuesta aceptada
Azzi Abdelmalek
el 11 de Ag. de 2016
Editada: Azzi Abdelmalek
el 11 de Ag. de 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 comentarios
Azzi Abdelmalek
el 11 de Ag. de 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
Más respuestas (2)
Peter Perkins
el 11 de Ag. de 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 comentarios
John D'Errico
el 11 de Ag. de 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.)
Ver también
Categorías
Más información sobre Logical 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!