C#百分位排序算法

C#百分位排序算法,c#,math,statistics,C#,Math,Statistics,我正在尝试对一个旧程序进行逆向工程计算,但不能完全得到它。我需要计算出顶部27%、中间46%和底部27%中有多少个值 我有以下数据集,每个数据集有11个值,以及程序产生的百分比和属于这些百分位数的值的数量 Upper 27%: 4, Middle 46%: 4, Lower 27%: 3 values: 8,9,10,11,11,11,11,12,12,12,13 Upper 27%: 5, Middle 46%: 4, Lower 27%: 2 values: 2,3,4,4,4,4,5,5

我正在尝试对一个旧程序进行逆向工程计算,但不能完全得到它。我需要计算出顶部27%、中间46%和底部27%中有多少个值

我有以下数据集,每个数据集有11个值,以及程序产生的百分比和属于这些百分位数的值的数量

Upper 27%: 4, Middle 46%: 4, Lower 27%: 3
values: 8,9,10,11,11,11,11,12,12,12,13

Upper 27%: 5, Middle 46%: 4, Lower 27%: 2
values: 2,3,4,4,4,4,5,5,5,5,5

Upper 27%: 2, Middle 46%: 8, Lower 27%: 1
values: 2,4,4,4,4,4,4,4,4,5,5

Upper 27%: 2, Middle 46%: 6, Lower 27%: 3
values: 13,17,17,18,19,19,19,21,21,23,24
我发现了(n*p)这样的公式,其中n是值的数量,p是百分位数,但它似乎不适用于所有这些数据集,以给出相同的结果。我有点迷路了,还没有找到任何能产生结果的东西

我已经测试了在互联网上找到的代码,但没有一个能在不同的数据集上工作

我尝试过的代码示例:

    internal static double percentile(double[] sortedData, double p)
    {
        if (p >= 100.0d) return sortedData[sortedData.Length - 1];

        double position = (double)(sortedData.Length + 1) * p / 100.0;
        double leftNumber = 0.0d, rightNumber = 0.0d;

        double n = p / 100.0d * (sortedData.Length - 1) + 1.0d;

        if (position >= 1)
        {
            leftNumber = sortedData[(int)System.Math.Floor(n) - 1];
            rightNumber = sortedData[(int)System.Math.Floor(n)];
        }
        else
        {
            leftNumber = sortedData[0]; // first data
            rightNumber = sortedData[1]; // first data
        }

        if (leftNumber == rightNumber)
            return leftNumber;
        else
        {
            double part = n - System.Math.Floor(n);
            return leftNumber + part * (rightNumber - leftNumber);
        }
    } 

有没有一个公式或名称来描述我正在尝试做的事情?我在百分位排名的正确轨道上吗?

你在正确的道路上。这确实是百分位排名公式。我最初的想法是得到第27个百分位的值(从代码中看,似乎也是从这条路径开始的),并计算出有多少个值大于或小于;但是您提供的值不能很好地支持这些数字

因此,我采取的方法是计算每个数字的百分位数排名,如果它们与上面的百分位数匹配,则将其放入计数中。这似乎是他们采取的方法

公式:

PR%=L+(0.5 x S)/N
哪里
L=低于职级的人数,
S=相同等级的数量,
N=总数。

代码:

var下限=0;
var中间值=0;
var上限=0;
//var值=新的int[]{8,9,10,11,11,11,11,12,12,13};
//var值=新的int[]{2,3,4,4,4,4,5,5,5};
//var值=新的int[]{2,4,4,4,4,4,4,4,4,5};
var值=新的int[]{13,17,17,18,19,19,19,21,21,23,24};
var n=值。长度;
foreach(值中的var i)
{
var pr=(.values.Count(v=>vv==i))/n);
如果(pr<.27)
较低+=1;
否则如果(pr>0.73)
上限+=1;
其他的
中等+=1;
}
控制台写入线(“上:+上”);
控制台。写入线(“中间:+Middle”);
控制台写入线(“下:+下”);

您走的是正确的道路。这确实是百分位排名公式。我最初的想法是得到第27个百分位的值(从代码中看,似乎也是从这条路径开始的),并计算出有多少个值大于或小于;但是您提供的值不能很好地支持这些数字

因此,我采取的方法是计算每个数字的百分位数排名,如果它们与上面的百分位数匹配,则将其放入计数中。这似乎是他们采取的方法

公式:

PR%=L+(0.5 x S)/N
哪里
L=低于职级的人数,
S=相同等级的数量,
N=总数。

代码:

var下限=0;
var中间值=0;
var上限=0;
//var值=新的int[]{8,9,10,11,11,11,11,12,12,13};
//var值=新的int[]{2,3,4,4,4,4,5,5,5};
//var值=新的int[]{2,4,4,4,4,4,4,4,4,5};
var值=新的int[]{13,17,17,18,19,19,19,21,21,23,24};
var n=值。长度;
foreach(值中的var i)
{
var pr=(.values.Count(v=>vv==i))/n);
如果(pr<.27)
较低+=1;
否则如果(pr>0.73)
上限+=1;
其他的
中等+=1;
}
控制台写入线(“上:+上”);
控制台。写入线(“中间:+Middle”);
控制台写入线(“下:+下”);

实现算法反向工程尝试的代码看起来不错……请向我们提供一个明确的问题,并向我们展示您的尝试(发布一些代码)。实现算法反向工程尝试的代码看起来不错……请向我们提供一个明确的问题,并向我们展示您的尝试(发布一些代码).你太棒了。我没有比你最初的方法走得更远。那是我一直在尝试的。是的,我一开始很挠头,但任何涉及舍入的时候都有统计错误的空间。你太棒了。我没有比你最初的方法走得更远。那是我一直在尝试的。是的,我一开始很挠头,但任何时候都可能出现错误如果涉及数据挖掘,则存在统计误差的空间。
var lower = 0;
var middle = 0;
var upper = 0;

// var values = new int[] { 8, 9, 10, 11, 11, 11, 11, 12, 12, 12, 13 };
// var values = new int[] { 2, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
// var values = new int[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5 };
var values = new int[] { 13, 17, 17, 18, 19, 19, 19, 21, 21, 23, 24 };

var n = values.Length;

foreach(var i in values)
{
    var pr = ((values.Count(v => v < i) + (.5 * values.Count(v => v == i))) / n);
    if (pr < .27)
        lower += 1;
    else if (pr > .73)
        upper += 1;
    else
        middle += 1;
}

Console.WriteLine("Upper: " + upper);
Console.WriteLine("Middle: " + middle);
Console.WriteLine("Lower: " + lower);