Процентильный расчет - PullRequest
       12

Процентильный расчет

21 голосов
/ 15 ноября 2011

Я хочу имитировать эквивалентную PERCENTILE функцию Excel в C# (или в некотором псевдокоде). Как я могу это сделать? Функция должна принимать два аргумента, где первый - это список значений, а второй - для какого процентиля функция должна рассчитывать.

Танки!

Редактировать: Извините, если мой вопрос встретился, как будто я не пробовал сам. Я просто не мог понять, как работает функция Excel (да, я сначала попробовал Википедию и Вольфрама), и я подумал, что пойму это лучше, если кто-то представит это в коде. @CodeInChaos дал ответ, который, кажется, мне нужен.

Ответы [ 3 ]

33 голосов
/ 15 ноября 2011

Я думаю На странице Википедии есть формулы, необходимые для написания собственной функции ...
Я попробовал это:

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]);
    }
}

ИЗМЕНЕНО после комментария CodeInChaos:
В Excel используется значение процентиля от 0 до 1 (поэтому я изменил свой код для реализации этого с помощью формул Википедии), а другой метод - для вычисления n (поэтому я изменил закомментированное).

15 голосов
/ 15 ноября 2011

Пытаясь воспроизвести результаты по адресу: http://www.techonthenet.com/excel/formulas/percentile.php Я придумал:

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];
}

(не обрабатывает NaN и бесконечности).

Несколько тестовых случаев:

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
0 голосов
/ 15 ноября 2011

Добавьте значения в список, отсортируйте этот список и возьмите значение индекса ceil (длина списка * процентиль).

...