I want to mimic the Excel equivalent PERCENTILE function in C#
(or in some pseudo code). How can I do that? The function should take two arguments where the first is a list of values and the second is for what percentile the function should calculate for.
Tanks!
Edit: I'm sorry if my question came across like I had not tried it my self. I just couldn't understand how the excel function worked (yes, I tried wikipedia and wolfram first) and I thought I would understand it better if someone presented it in code. @CodeInChaos gave an answer that seem to be what I'm after.
The 95th percentile basically says that 95 percent of the time your usage is at or below it, and the other 5 percent of the time it exceeds it. Data points. These are the pieces of data you have collected.
Arrange the numbers in ascending order and give the rank ranging from 1 to the lowest to 4 to the highest. Use the formula: 3=P100(4)3=P2575=P. Therefore, the score 30 has the 75 th percentile.
I think Wikipedia page has formulas you need to write your own function...
I tried this:
public double Percentile(double[] sequence, double excelPercentile) { Array.Sort(sequence); int N = sequence.Length; double n = (N - 1) * excelPercentile + 1; // Another method: double n = (N + 1) * excelPercentile; if (n == 1d) return sequence[0]; else if (n == N) return sequence[N - 1]; else { int k = (int)n; double d = n - k; return sequence[k - 1] + d * (sequence[k] - sequence[k - 1]); } }
EDITED after CodeInChaos comment:
Excel uses a percentile value between 0 and 1 (so I changed my code to implement this with Wikipedia formulas) and the other method to calulate n (so I changed the commented one).
Trying to reproduce the results at: http://www.techonthenet.com/excel/formulas/percentile.php I came up with:
public static double Percentile(IEnumerable<double> seq,double percentile) { var elements=seq.ToArray(); Array.Sort(elements); double realIndex=percentile*(elements.Length-1); int index=(int)realIndex; double frac=realIndex-index; if(index+1<elements.Length) return elements[index]*(1-frac)+elements[index+1]*frac; else return elements[index]; }
(Does not handle NaN
and infinities).
A few test cases:
Percentile(new double[]{1,2,3,4}, 0.8).Dump();// 3.4 Percentile(new double[]{7,8,9,20}, 0.35).Dump();// 8.05 Percentile(new double[]{1,2,3,4}, 0.3).Dump();// 1.9
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With