У меня есть интересная задача Javascript (выполненная в Node.js, FWIW): мне нужно взять «взвешенную медиану» набора данных, для которого у меня есть значения (в данном случае доход) и вес для каждого из них. Например:
income #people
0 5
16000 3
20000 8
32000 4
40000 3
41000 1
50000 2
90000 1
Другими словами, 8 человек зарабатывают 20 тысяч долларов, 2 — 50 тысяч долларов и т. д. Мне нужна «взвешенная медиана» — медиана всех 27 человек.
Наивным способом сделать это было бы создать массив и заполнить его каждым значением, например так:
var incomes = [0, 0, 0, 0, 0, 16000, 16000, 16000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 32000, 32000, 32000, 32000, 40000, 40000, 40000, 41000, 50000, 50000, 90000];
Затем можно легко взять медиану этого массива (что составляет 20 000 долларов). На самом деле у меня есть данные от 7 000 до 14 000 человек на выборку. Хотя я уверен, что Node справится с таким большим массивом, он кажется невероятно неаккуратным.
Мое текущее решение состоит в том, чтобы вычислить индекс медианного значения в гипотетическом подробном массиве — 13, в данном случае — и пройтись по массиву доходов и весов, складывая совокупный вес до тех пор, пока он не достигнет или не превысит точку на полпути. . Вот упрощенный пример. (Очевидно, что медианы требуют несколько иных правил для списков с четными номерами. Это просто POC.)
var halfway = 13,
progress = 0;
var vals = [[0,5], [16000,3], [20000,8], [32000,4], [40000,3], [41000,1], [50000,2], [90000,1]];
for (var v = 0; v < vals.length; v += 1) {
progress += vals[v][1];
if (progress >= halfway) {
var median = vals[v][0];
break;
}
}
Это работает нормально, но становится грязным, когда вы хотите начать вычислять квартили и так далее. Что было бы проще для меня, так это иметь возможность создать разреженный массив значений в соответствующем месте в подробном массиве, не заполняя все промежуточные значения, а затем выполнять поиск в этом массиве для любого индекса до максимума. Но мне нужен эффективный механизм для поиска предыдущего известного индекса в разреженном массиве, если (что вполне вероятно) индекс, который я ищу в запасном массиве, не заполнен.
Кажется, это должна быть довольно распространенная проблема.
vals.forEach(function (element, i, array){});
- person DrakaSAN   schedule 24.09.2014