Domanda

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.

È stato utile?

Soluzione

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).

Altri suggerimenti

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

Add the values to a list, sort that list, and take the index value ceil(length of the list * percentile).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top