La agrupación de números para un histograma
Pregunta
Tengo un montón de números que desea utilizar para generar un histograma para una puntuación estándar.
Por lo tanto calcular la media y la desviación estándar de los números y normalizar cada x con esta fórmula
x'= (x-media) / desv_están
El resultado es un número entre -4 y 4. Quiero trazar ese resultado. Busco a una forma de agrupar los números en orden para evitar que pequeños bares.
Mi plan es tener contenedores en el intervalo [4,4] centrado en unidades trimestrales consecutavice, es decir [-4, -3.75, ..., 3.75,4]
Ejemplo: 0.1 => bin "0,0", 0,3 => bin "0,25", -1,3 => Bin "-1,5"
¿Cuál es la mejor manera de lograr eso?
Solución
He aquí una solución que no utiliza ninguna bibliotecas tercera parte. Los números deben estar en el vals
matriz.
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
Creo que realiza el redondeo adecuado. Pero sólo probado con:
vals = Array.new(10000) { (rand * 10) % 4 * (rand(2) == 0 ? 1 : -1) }
y la distribución sesgada consiguió especie de, pero eso es probablemente culpa del generador de números aleatorios.
Otros consejos
Rieles proporciona Enumerable # group_by - ver fuente aquí, suponiendo que no se esté usando Rails: http://api.rubyonrails.org/classes/Enumerable.html
Asumiendo que su lista se llama XS, se podría hacer algo como lo siguiente (no probado):
bars = xs.group_by {|x| #determine bin here}
A continuación, tendrá un hash que se parece a:
bars = { 0 => [elements,in,first,bin], 1 => [elements,in,second,bin], etc }