2016-03-28 2 views
1

Im создает алгоритм гистограммы. Im после предлагаемого решения here.Простой алгоритм гистограммы в Javascript

Я хочу просто подсчитать количество раз, когда произошло каждое значение.

Однако я не могу получить алгоритм правильно. Мой код:

var values = [2, 4, 6, 3, 3]; 

var val_max = 6; 
var val_min = 2; 

var num_bins = parseInt(val_max - val_min + 1); 
console.log('num_bins is ', num_bins); 

var bin_width = (val_max-val_min)/num_bins; 
console.log('bin_width is ', bin_width); 

var to_plot = []; 

for (var i = 0; i < num_bins; i++) { 
    to_plot.push(0); 
} 

for (var x = 0; x < values.length; x++) { 

    var bin_idx = parseInt((values[x] - val_min)/bin_width); 

    to_plot[bin_idx] = to_plot[bin_idx] + 1; 
} 

console.log('to_plot is ', to_plot); 

Если вы посмотрите на журналы консоли, вы увидите:

to_plot is [1, 2, 1, 0, 0, NaN] 

Я хочу, чтобы последний индекс, чтобы быть «1». Но проблема в том, что значения закрывают максимальное значение, bin_idx выходит за пределы допустимого диапазона. Как я могу настроить это, чтобы получить следующие результаты?

to_plot is [1, 2, 1, 0, 1] 

Jsfiddle - here.

ответ

2

Вот что я хотел бы сделать:

var data = [2, 4, 6, 3, 3]; 
 

 
print(histogram(data, 1)); // [1, 2, 1, 0, 1] 
 
print(histogram(data, 2)); // [3, 1, 1] 
 
print(histogram(data, 3)); // [4, 1] 
 
print(histogram(data, 4)); // [4, 1] 
 
print(histogram(data, 5)); // [5] 
 

 
function histogram(data, size) { 
 
    var length = data.length; 
 

 
    var min = data[0]; 
 
    var max = data[1]; 
 

 
    for (var i = 0; i < length; i++) { 
 
     var item = data[i]; 
 
     if (item < min) min = item; 
 
     else if (item > max) max = item; 
 
    } 
 

 
    var bins = Math.ceil((max - min + 1)/size); 
 

 
    var histogram = new Array(bins); 
 

 
    for (var i = 0; i < bins; i++) histogram[i] = 0; 
 

 
    for (var i = 0; i < length; i++) 
 
     histogram[Math.floor((data[i] - min)/size)]++; 
 

 
    return histogram; 
 
} 
 

 
function print(x) { 
 
    alert(JSON.stringify(x)); 
 
}

Это работает для нецелых значений тоже.

+0

Фантастическое решение. Это работает очень хорошо. Похоже, мне придется использовать логарифмический масштаб, поскольку некоторые значения слишком велики. Так что это работает очень хорошо, так как плохо работать с поплавками. Благодаря! – Mark

1

Я думаю, что ваш bin_width ошибочен. Попробуйте этот расчет вместо:

var bin_width = (val_max - val_min)/(num_bins - 1); 

Это делает bin_width == 1, которая позволяет остальной части вашего кода работы.

+0

, который работает благодаря – Mark

1

Поскольку количество ячеек равно числу целых чисел между val_min и val_max, bin_width составляет 1, а не 0,8, как рассчитывается в настоящее время. Вы в основном считаете целые числа здесь. Используйте этот цикл для создания гистограммы:

for (var x = 0; x < values.length; x++) { 
    to_plot[values[x] - val_min] ++; 
} 
+0

Да, верно, плохо пойти с этим решением – Mark

Смежные вопросы