我想在C#
(或在某些伪代码中)模仿 Excel 等效的 PERCENTILE 函数。我怎样才能做到这一点?该函数应该有两个参数,第一个是值列表,第二个是函数应该计算的百分位数。
坦克!
编辑:如果我的问题像我自己没有尝试过一样,我很抱歉。我只是无法理解 excel 函数是如何工作的(是的,我首先尝试了 wikipedia 和 wolfram),我想如果有人用代码呈现它,我会更好地理解它。@CodeInChaos 给出的答案似乎是我所追求的。
我想在C#
(或在某些伪代码中)模仿 Excel 等效的 PERCENTILE 函数。我怎样才能做到这一点?该函数应该有两个参数,第一个是值列表,第二个是函数应该计算的百分位数。
坦克!
编辑:如果我的问题像我自己没有尝试过一样,我很抱歉。我只是无法理解 excel 函数是如何工作的(是的,我首先尝试了 wikipedia 和 wolfram),我想如果有人用代码呈现它,我会更好地理解它。@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 之间的百分位值(因此我更改了代码以使用 Wikipedia 公式实现此功能)和另一种计算 n 的方法(因此我更改了注释的那个)。
试图重现结果: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
将值添加到列表中,对该列表进行排序,并获取索引值 ceil(列表长度 * 百分位数)。