Нахождение процентилей в отсортированном массиве - PullRequest
0 голосов
/ 08 октября 2019

Я пишу некоторый код и хочу знать, правильно ли я вычисляю процентили в отсортированном массиве. В настоящее время, если я хочу вычислить, скажем, 90-й процентиль, я делаю это: ARR [(9 * (N + 1)) / 10]. Или, скажем, я вычисляю 50-й процентиль в отсортированном массиве, я делаю это: ARR [(5 * (N + 1)) / 10]. В более общем смысле, чтобы вычислить x-й процентиль, я проверяю индекс [x / 100 * (N + 1)], где N - размер массива.

Кажется, они работают, но я просто думаю,если возможно есть какой-то крайний случай, который я пропускаю. Например, скажем, у вас есть только 5 элементов. Каким должен быть 90-й процентиль? Это должно быть самое большое значение?

Заранее спасибо

1 Ответ

0 голосов
/ 10 октября 2019

Например, скажем, у вас есть только 5 элементов. Каким должен быть 90-й процентиль? Это должно быть наибольшее значение?

Да. Если вы выберете определение типа (это просто скопировано из Wikipedia )

P-го процентиля списка из N упорядоченных значений (отсортированных от наименьшего к наибольшему)является наименьшим значением в списке, так что не более P процентов данных строго меньше значения и, по крайней мере, P процентов данных меньше или равно этому значению

5-го числаэлемент может быть 90-м процентилем:

  • не более P процентов данных строго меньше значения : 80% данных строгоменьше самого большого элемента, который составляет не более 90%
  • , по крайней мере P процентов данных меньше или равно этому значению : 100% отданные меньше или равны 5-му элементу, который составляет не менее 90%

. И 5-й элемент является наименьшим, который может это сделать (даже если 4-й и 5-й элементы равны,5-й элемент по-прежнему самый маленький, потому что процентиль яо значении, а не о позиции).

Для тонкой настройки формулы более интересны граничные случаи - например, 79-80-81-й процентиль списка из 5 элементов

element index:     0       1       2       3       4
strictly less:     0%     20%     40%     60%     80%
less or equal:    20%     40%     60%     80%    100%

79-й процентиль: ожидается 4-й (60% <79%, 79% <= 80%) 80-й процентиль: ожидается 4-й (60% <80%, 80% <= 80%) 81-й процентиль: ожидается 5-й (80%<81%, 81% <= 100%) </p>

Это похоже на округление чего-либо (индексы дроби) вверх (зная, что 80 - это граница, и глядя на отображения 79-> 3, 80-> 3, но81-> 4). Функция обычно называется что-то вроде ceil(), Math.ceil() (вопрос не определяет язык программирования на данный момент)

 P    5*P/100    ceil(5*P/100)     (5=N)
79      3.95        4
80      4           4
81      4.05        5

((N+1) выдаст 4,74, 4,8, 4,86, так что это безопасноскажем, +1 не требуется)
И, таким образом, ceil(N*P/100) действительно, кажется, один (конечно, это тоже в Википедии, всего на 2-3 строки ниже определения)

Обратите внимание, что языки программированияможет добавлять различные причуды:

  • массивы / списки часто индексируются с 0
  • результат ceil() может потребоваться преобразовать в целое число
  • и подлыйпервый: если N и P являются целыми числами, вам может потребоваться убедиться, что деление не является целочисленным делением (автоматическое отбрасывание дробной части, поэтому результат округляется вниз).

Строка Java будет выглядеть примерно так:

int index=(int)Math.ceil(N*P/100.0)-1;

Если вы хотите 0-й процентиль, она может обрабатываться отдельно или взламываться в той же строке с помощью max()

public static int percentile(int array[],float P) {
  return array[Math.max(0,
    Math.min(array.length, (int)Math.ceil(array.length*P/100))-1)];
}

(Этот также использует min() и будет производить некоторыерезультат для любого конечного P, неявно усекающего его в диапазон 0 <= P <= 100) </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...