如何在Ruby中从平面数组创建直方图

时间:2013-09-30 18:26:35

标签: ruby histogram

如何创建整数数组的直方图?例如:

data = [0,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,5,5,6,6,6,7,7,7,7,7,8,9,9,10]

我想根据012等条目的数量来创建直方图。在Ruby中有一种简单的方法吗?

输出应该是两个数组。第一个数组应包含组(bin),第二个数组应包含出现次数(频率)。

对于上面给出的data,我希望得到以下结果:

bins         # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
frequencies  # => [1, 1, 5, 6, 4, 2, 3, 5, 1, 2, 1]

2 个答案:

答案 0 :(得分:46)

Ruby的数组继承group_by from Enumerable,这很好地做到了这一点:

Hash[*data.group_by{ |v| v }.flat_map{ |k, v| [k, v.size] }]

返回:

{
     0 => 1,
     1 => 1,
     2 => 5,
     3 => 6,
     4 => 4,
     5 => 2,
     6 => 3,
     7 => 5,
     8 => 1,
     9 => 2,
    10 => 1
}

这只是一个很好的'干净哈希。如果你想要一个每个bin和频率对的数组,你可以缩短它并使用:

data = [0,1,2,2,3,3,3,4]
data.group_by{ |v| v }.map{ |k, v| [k, v.size] }
# => [[0, 1], [1, 1], [2, 2], [3, 3], [4, 1]]

以下是代码和group_by对较小数据集的作用:

data.group_by{ |v| v }    
# => {0=>[0], 1=>[1], 2=>[2, 2], 3=>[3, 3, 3], 4=>[4]}

data.group_by{ |v| v }.flat_map{ |k, v| [k, v.size] }  
# => [0, 1, 1, 1, 2, 2, 3, 3, 4, 1]

答案 1 :(得分:8)

使用此宝石 - http://rubygems.org/gems/histogram

data = [0,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,5,5,6,6,6,7,7,7,7,7,8,9,9,10]
(bins, freqs) = data.histogram 

这将创建一个数组bins,其中包含直方图的区间和包含频率的数组freqs。 gem还支持不同的分箱行为和权重/分数。

希望这有帮助。