Ruby Array组和平均小时

时间:2009-12-04 10:19:28

标签: ruby arrays structure hash

我们从传感器获取数据,该传感器记录和存储哈希等数据。 它可以随时测量一些类似的东西:

{:temperature => 30, :pression => 100, :recorded_at => 14:34:23}
{:temperature => 30, :pression => 101, :recorded_at => 14:34:53}
{:temperature => 31, :pression => 102, :recorded_at => 14:34:24}
{:temperature => 30, :pression => 101, :recorded_at => 14:34:55}
{:temperature => 30, :pression => 102, :recorded_at => 14:34:25}
{:temperature => 31, :pression => 101, :recorded_at => 14:34:56}

我们需要能够以JSON格式导出数据,但是我们有太多数据(传感器记录大约每30秒),我们需要删除一些数据。理想情况下,我们希望在过去24小时内每小时导出1个小节,因此我们有类似

的内容
{0 => {:temperature => 30, :pression => 100}, 1 => {:temperature => 30, :pression => 100}, 2 => {:temperature => 30, :pression => 100}, 3 => {:temperature => 30, :pression => 100}, 4 => {:temperature => 30, :pression => 100}}

对于每小时,温度是该小时内测量的所有温度的平均值。 此外,如果出于任何原因,1小时内缺少某些数据,我想以前一小时和下一小时之间的平均值来推断它。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

更多功能版本(简单插入缺失值)

probs = [{:temperature => .. }] # array of measurings

def average(list, key)
  list.reduce(0){|acc,el| acc+el[key]} / list.length unless list.empty
end

prob_groups = probs.group_by{|prob| prob[:recorded_at][0,2].to_i}
average_groups = prob_groups.map do |hour,prob_group|
  { hour => {
      :temperature => average(prob_group, :temperature),
      :pression    => average(prob_group, :pression)
  }}
end.reduce{|acc,el| acc.merge(el)}

def interpolate(p, n, key)
  (p[key] + n[key])/2 unless p.nil? || n.nil? || p[key].nil? || n[key].nil?
end

resuls = (1..24).map do |hour|
  if average_groups[hour]
    { hour => average_groups[hour] }
  else
    { hour => {
      :temperature => interpolate(average_groups[hour-1], average_groups[hour+1], :temperature),
      :pression => interpolate(average_groups[hour-1], average_groups[hour+1], :pression)
    }}
  end
end.reduce{|acc,el| acc.merge(el)}

希望它有效

答案 1 :(得分:2)

类似这样的事情

t = [....] - array of measurings
result = {}

(1..24).each do|hour| 
    #  measurings of given hour
    measurings = t.select{|measuring| measuring[:recorded_at][0, 2].to_i == hour}

    #  average temperature of hour
    sum = measurings.inject(0){|sum, measuring| sum + measuring[:temperature].to_i} 
    average_temperature = (measurings.length == 0)? nil: sum/measurings.length.to_f

    result[hour] = average_temperature
end

答案 2 :(得分:0)

如果您对历史感兴趣,但仅对实际值的近似值感兴趣,请考虑使用“移动指标”(http://en.wikipedia.org/wiki/Moving_average)。

相关问题