Процентный расчет
Я хочу подражать функции PERCENTILE, эквивалентной Excel, в C#
(или в некотором псевдокоде). Как я могу это сделать? Функция должна принимать два аргумента, где первый - это список значений, а второй - для того, для какого процентиля должна вычисляться функция.
Танки!
Изменить: Прошу прощения, если мой вопрос натолкнулся, как будто я не пробовал это сам. Я просто не мог понять, как работает функция excel (да, я сначала пробовал википедию и вольфрам), и я подумал, что лучше пойму, если кто-то представит ее в коде.
@CodeInChaos дал ответ, который кажется тем, что мне нужно.
Ответы
Ответ 1
Я думаю, страница Wikipedia содержит формулы, необходимые для написания вашей собственной функции...
Я пробовал это:
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 после комментария CodeInChaos:
Excel использует значение процентиля между 0 и 1 (поэтому я изменил свой код, чтобы реализовать его с помощью формул Википедии), а другой метод для вычисления n (поэтому я изменил комментарий).
Ответ 2
Попытка воспроизвести результаты по адресу: 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
Ответ 3
Добавьте значения в список, отсортируйте этот список и возьмите значение индекса ceil (длина списка * процентиль).