2016-03-28 18 views
1

Im Erstellen eines Histogramm-Algorithmus. Ich folge der angebotenen Lösung here.Einfacher Histogramm-Algorithmus in Javascript

Ich möchte einfach zählen, wie oft jeder Wert aufgetreten ist.

Allerdings kann ich den Algorithmus nicht richtig bekommen. Mein Code ist:

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); 

Wenn man sich die Konsolenprotokolle suchen, werden Sie sehen:

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

Ich möchte, dass im letzten Index "1" sein. Aber das Problem ist, dass Werte den Maximalwert schließen, bin_idx ist außerhalb des Bereichs. Wie kann ich das optimieren, damit ich die folgenden Ergebnisse bekomme?

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

Die jsfiddle ist here.

Antwort

2

Hier ist, was ich tun würde:

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)); 
 
}

Auch das nicht-ganzzahlige Werte arbeitet für.

+0

Fantastische Lösung. Das funktioniert sehr gut. Es sieht so aus, als müsste ich eine logarithmische Skala verwenden, da einige Werte viel zu groß sind. Das funktioniert also sehr gut, da ich mit Schwimmern arbeite. Vielen Dank! – Mark

1

Ich denke, Ihre bin_width ist falsch. Versuchen Sie, diese Berechnung statt:

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

, dass die bin_width == 1 macht, die den Rest des Codes arbeiten können.

+0

das funktioniert dank – Mark

1

Da die Anzahl der Bins gleich der Anzahl der ganzen Zahlen zwischen val_min und val_max ist, ist bin_width 1, nicht 0.8, wie derzeit berechnet wird. Du zählst hier ganze Zahlen. Verwenden Sie diese Schleife um das Histogramm zu generieren:

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

Ja stimmt, gehen Sie mit dieser Lösung – Mark