Skip to content

Instantly share code, notes, and snippets.

@guitarrapc
Last active July 14, 2020 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guitarrapc/fd8c663c34582081ae665a7232529efe to your computer and use it in GitHub Desktop.
Save guitarrapc/fd8c663c34582081ae665a7232529efe to your computer and use it in GitHub Desktop.
Calculate Percentile
void Main()
{
var data = new double[] { 2, 4, 6, 8, 13, 16, 22, 35, 40, 42, 48 };
var percs = new[] { 0.5, 0.66, 0.75, 0.80, 0.90, 0.95, 0.98, 0.99, 1.00 };
percs.Select(x =>
{
var percent = (int)(x * 100);
var percentile = MathUtil.Percentile(data, x);
var percentileInterpolation = MathUtil.PercentileInterpolation(data, x);
return new Result(percent, percentile, percentileInterpolation);
})
.Dump();
}
public struct Result
{
public int Percent { get; set; }
public double Percentile { get; set; }
public double PercentileInterpolation { get; set; }
public Result(int percent, double percentile, double percentileInterpolation)
{
Percent = percent;
Percentile = percentile;
PercentileInterpolation = percentileInterpolation;
}
}
public static class MathUtil
{
public static double Percentile(double[] sortedSequence, double percentile)
{
var n = sortedSequence.Length;
var realIndex = Round((n - 1) * percentile);
var rank = (int)realIndex;
var flac = realIndex - rank;
if (rank + 1 < n)
{
return Round(sortedSequence[rank] * (1 - flac) + sortedSequence[rank + 1] * flac);
}
else
{
return sortedSequence[rank];
}
}
public static double PercentileInterpolation(double[] sortedSequence, double percentile)
{
var n = sortedSequence.Length;
var realIndex = Round((n + 1) * percentile) - 1;
var rank = (int)realIndex;
var flac = realIndex - rank;
if (rank >= n)
{
// last
return sortedSequence[n - 1];
}
else if (flac == 0)
{
// when index match to rank
return sortedSequence[rank];
}
else if (rank + 1 < n)
{
// calculate interpolation
return Round(sortedSequence[rank] + (sortedSequence[rank + 1] - sortedSequence[rank]) * flac);
}
else
{
return sortedSequence[rank];
}
}
private static double Round(double value, int digit = 2)
{
return System.Math.Round(value, digit, MidpointRounding.AwayFromZero);
}
}
Percent Percentile PercentileInterpolation
50 16 16
66 29.8 33.96
75 37.5 40
80 40 41.2
90 42 46.8
95 45 48
98 46.8 48
99 47.4 48
100 48 48
753 352.5 369.96
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment