Ruby范围,数字数组?

时间:2014-07-25 17:32:11

标签: ruby arrays

我尝试使用[0,1]范围内的数字数组创建直方图。

有没有办法使用group_by按数字间隔(或其他一些有趣的Ruby单行程序)将数组分成N组/ bin?

这是我目前无聊的解决方案:

# values == array containing floating point numbers in the range [0,1]

n = 10

# EDITED from Array.new(n, 0) to Array.new(n, []), thanks emaillenin!
histogram = Array.new(n, [])
values.each do |val|
  histogram[(val * n).ceil - 1].push(val)
end

2 个答案:

答案 0 :(得分:3)

不确定你要做什么,但也许这有帮助?

values = [0.0, 0.1, 0.2, 0.3]
values.group_by { |v| (v * 10).ceil - 1 }

返回哈希:

{-1=>[0.0], 0=>[0.1], 1=>[0.2], 2=>[0.3]}

答案 1 :(得分:1)

这是一种方法。

<强>代码

def freq_by_bin(nbr_bins, *values)
  nbr_bins.times.to_a.product([0]).to_h.tap { |h|
    values.each { |v| h.update({ (v*nbr_bins).to_i=>1 }) { |_,o,_| o+1 } } }
end

示例

values =  [0.30, 0.25, 0.63, 0.94, 0.08, 0.94, 0.01,
           0.41, 0.28, 0.69, 0.61, 0.12, 0.66]
freq_by_bin(10, *values)
  #=> {0=>2, 1=>1, 2=>2, 3=>1, 4=>1,
  #    5=>0, 6=>4, 7=>0, 8=>0, 9=>2}

def histogram(nbr_bins, *values)
  h = freq_by_bin(nbr_bins, *values)
  puts "\nfreq"
  h.values.max.downto(0) do |n|
    print "%2d|" % n
    puts nbr_bins.times.with_object('   ') { |i,row|
           row << ((h[i]==n) ? ' X ' : '   ') }
  end
  puts "   __"+"___"*nbr_bins
  puts nbr_bins.times.each_with_object('      ') { |i,row| row << "%2d " % i }
end

histogram(10, *values)

freq
 4|                      X          
 3|                                 
 2|    X     X                    X 
 1|       X     X  X                
 0|                   X     X  X    
   ________________________________
       0  1  2  3  4  5  6  7  8  9 

备注

  • 有几种方法可以构造其元素为bin=>freq的哈希。使用Enumerable#group_by,你提到的和@diego使用的是一个。我使用Hash#update(又名Hash#merge!)的形式进行了阻止。

  • 我只使用Object#tap来避免为初始化哈希创建临时(非块)变量。