如何计算目标数据在数据集中所处分位(Java实现)

分位值在数据分析中是一个比较常见的需求,计算一组数据的分位值,例如P10、P50等,有很多现成的Java实现,例如Guava的Quantiles类,以及org.apache.commons.math.stat下的相关实现,在此不赘述。
计算某个数据,在一组数中的所处分位,即Excel中PERCENTRANK,分为两种情况:

  • 若目标数包含在数组中,则所处分位 = 小于该数的数据量 / (数据总量 - 1)
  • 若目标数不在数组中,则它的所处分位,由与他相领的两个数的所处分位计算而来,具体为(以目标数据为b,与他相领的数据为a,c为例):
    Pb = Pa + ((b-a)/(c-a))*(Pc-Pa)
    以下是Java实现:
public static String getPosition(List<Number> data, double target) {
    double[] doubles = Doubles.toArray(data);
    // 需要对数据进行排序
    Arrays.sort(doubles);
    double result;
    // 小于目标值的数量
    int lt = 0;
    // 如果是第二种情况,则用lt2来记录比a小的数据量,它等于比c小的数据量减去a出现的次数。
    int lt2 = 1;
    int pos = -1;
    double a = NaN;
    double c = NaN;
    for (int i = 0; i < doubles.length; i++) {
        if (doubles[i] == target) {
            pos = i;
            break;
        } else if (doubles[i] < target) {
            lt++;
            if (doubles[i] == a) {
                lt2++;
            } else {
                lt2 = 1;
                a = doubles[i];
            }
        } else {
            c = doubles[i];
            break;
        }
    }
    // 若目标b不在数组中,则需要找到目标值临近的两个数(例如ac之于b)的位置,通过Pb = Pa + ((b-a)/(c-a))*(Pc-Pa)
    Pc: result = (double) lt / (doubles.length - 1);
    if (pos < 0) {
        double Pa = (double) (lt - lt2) / (doubles.length - 1);
        result = Pa + ((target - a)/ (c - a)) * (result - Pa);
    }
    return String.format("P%.0f", result * 100);
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容