Gruppieren von Zahlen für ein Histogramm
Frage
Ich habe eine Reihe von Zahlen, die ich verwenden mag ein Histogramm für ein Standard-Score zu erzeugen.
Deshalb berechnen ich den Mittelwert und die Standardabweichung der Zahlen und normalisieren jedes x mit dieser Formel
x‘= (x-Mittelwert) / std_dev
Das Ergebnis ist eine Zahl zwischen -4 und 4. Ich möchte dieses Ergebnis entwerfen. Ich bin für eine Art und Weise zu einer Gruppe suchen, um die Zahlen, um kleine Bars zu vermeiden.
Mein Plan ist Bins in dem Intervall haben [-4,4] bei consecutavice Quartal Einheiten zentriert, das heißt [-4, -3,75, ..., 3.75,4]
Beispiel: 0,1 => ist "0.0", 0.3 => ist "0,25", -1.3 => Bin "-1.5"
Was ist der beste Weg, das zu erreichen?
Lösung
Hier ist eine Lösung, die keine dritten Teil Bibliotheken nicht verwendet. Die Zahlen in der Array vals
sein sollten.
MULTIPLIER = 0.25
multipliers = []
0.step(1, MULTIPLIER) { |n| multipliers << n }
histogram = Hash.new 0
# find the appropriate "bin" and create the histogram
vals.each do |val|
# create an array with all the residuals and select the smallest
cmp = multipliers.map { |group| [group, (group - val%1).abs] }
bin = cmp.min { |a, b| a.last <=> b.last }.first
histogram[val.truncate + bin] += 1
end
Ich denke, dass es die richtige Rundung durchführt. Aber ich habe nur versucht, es mit:
vals = Array.new(10000) { (rand * 10) % 4 * (rand(2) == 0 ? 1 : -1) }
und die Verteilung bekam Art schief, aber das ist wahrscheinlich der zufällige Fehler des Zahlengenerators.
Andere Tipps
Rails Enumerable # group_by - siehe Quelle hier, Sie vorausgesetzt, sie nicht verwenden Rails: http://api.rubyonrails.org/classes/Enumerable.html
Unter der Annahme der Liste xs genannt wird, Sie so etwas wie die folgenden (ungetestet) tun könnte:
bars = xs.group_by {|x| #determine bin here}
Dann werden Sie einen Hash haben, die wie folgt aussieht:
bars = { 0 => [elements,in,first,bin], 1 => [elements,in,second,bin], etc }