Ruby Array to Histogram. How to group numbers by range? -
i need group array values range-based histogram in ruby...
values = [ 139, 145, 149, 151, 152, 153, 163, 166, 169 ]
for example:
141 - 145 = 2 146 - 150 = 1 151 - 155 = 3
...
is there simple way use group_by
?
to prepare histogram 1 specifies smallest value of first range, range size , number of ranges. pre-processing of data may necessary determine values. example, given
values = [139, 145, 149, 151, 152, 153, 164, 166, 169] group_size = 5
we might compute smallest value of first group , number of groups follows:
smallest, largest = values.minmax #=> [139, 169] start = group_size*(smallest/group_size) #=> 135 nbr_groups = ((largest-start+1)/group_size.to_f).ceil #=> 7
we can construct array can use create histogram.
def group_values(values, start, nbr_groups, group_size) groups = array.new(nbr_groups) |i| f = start + * group_size { nbr: 0, range: f..f+group_size-1 } end values.each_with_object(groups) { |v,arr| arr[(v-start)/group_size][:nbr] += 1 } end
let's try (for values of start
, nbr_groups
computed above).
freq = group_values(values, start, nbr_groups, group_size) #=> group_values(values, 135, 7, 5) #=> [{:nbr=>1, :range=>135..139}, # {:nbr=>0, :range=>140..144}, # {:nbr=>2, :range=>145..149}, # {:nbr=>3, :range=>150..154}, # {:nbr=>0, :range=>155..159}, # {:nbr=>1, :range=>160..164}, # {:nbr=>2, :range=>165..169}]
note that
- the value of
:range
each element of resulting array provided labeling horizontal axis of histogram. - i initialized array
groups
groups containing no elements ofvalues
(for values140-144
,155-159
) included in array returned. had constructed array on fly not have contained hashes 2 groups. - to establish range of frequencies vertical axis of histogram might compute following.
freq.map { |h| h[:nbr] }.minmax #=> [0, 3]
Comments
Post a Comment