我想在C#
(或伪代码)中模拟Excel中的PERCENTILE函数。我该怎么做?该函数应接受两个参数,其中第一个是值列表,第二个是要计算函数的百分位数。
谢谢!
编辑:如果我的问题让人觉得我没有尝试过,请原谅我。我只是不理解Excel函数是如何工作的(是的,我先查了维基百科和沃尔夫勒姆),我想如果有人用代码呈现出来,我就能更好地理解它。 @CodeInChaos给出了一个看起来符合我需要的答案。
我想在C#
(或伪代码)中模拟Excel中的PERCENTILE函数。我该怎么做?该函数应接受两个参数,其中第一个是值列表,第二个是要计算函数的百分位数。
谢谢!
编辑:如果我的问题让人觉得我没有尝试过,请原谅我。我只是不理解Excel函数是如何工作的(是的,我先查了维基百科和沃尔夫勒姆),我想如果有人用代码呈现出来,我就能更好地理解它。 @CodeInChaos给出了一个看起来符合我需要的答案。
我认为维基百科页面上有你需要编写自己的函数的公式...
我尝试了这个:
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(因此我更改了被注释的方法)。
return sequence[k - 1] + d * (sequence[k] - sequence[k - 1]);
)抛出了ArgumentOutOfRangeException异常。 - lost_in_the_source我试图复现这个网站上的结果: 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