如何计算阵列中15分钟范围内的数据?

时间:2013-03-06 10:14:58

标签: ruby-on-rails ruby ruby-on-rails-3

我有一系列时间段和数值:

2013-03-04 02:00:00 UTC
2013-03-04 02:01:00 UTC
2013-03-04 02:02:00 UTC
2013-03-04 02:03:00 UTC
2013-03-04 02:04:00 UTC
2013-03-04 02:05:00 UTC
2013-03-04 02:06:00 UTC
2013-03-04 02:07:00 UTC
2013-03-04 02:08:00 UTC
2013-03-04 02:09:00 UTC
2013-03-04 02:10:00 UTC
2013-03-04 02:11:00 UTC
2013-03-04 02:12:00 UTC
2013-03-04 02:13:00 UTC
2013-03-04 02:14:00 UTC
2013-03-04 02:15:00 UTC
2013-03-04 02:16:00 UTC
2013-03-04 02:17:00 UTC
2013-03-04 02:18:00 UTC
2013-03-04 02:19:00 UTC
2013-03-04 02:20:00 UTC
2013-03-04 02:21:00 UTC
2013-03-04 02:22:00 UTC
2013-03-04 02:23:00 UTC
2013-03-04 02:24:00 UTC
2013-03-04 02:25:00 UTC
2013-03-04 02:26:00 UTC
2013-03-04 02:27:00 UTC
2013-03-04 02:28:00 UTC
2013-03-04 02:29:00 UTC
2013-03-04 02:30:00 UTC

每个时间段都有自己的浮点数值。就像:

1.192069669
1.398097386
1.51857279
1.667887277
1.919998368
2.007405113
2.079283295
2.160574819
2.184922836
2.194639015
2.234917032
2.278915283
2.307196654
2.265553703
2.209039541
2.204034995
2.271997186
2.192411672
2.268617205
2.136996194
2.20568788
2.202653527
2.186529626
2.206325387
2.182503664
1.196174184
1.206075579
1.226468123
1.177213548
1.060684314
1.215226185
1.268223732
1.334227719
1.503234406
1.699964124
1.680645046
1.767723116
1.733957416
1.79358097
1.847852493
1.918378765
1.95619668
1.900485186
1.908825891
2.138246816
2.170221961
2.131884782
2.140921904
2.171028766
2.392254099
2.497088696

问题是:

我需要总结每个15分钟的值并采用他们的算术平均值。

例如,02:00和02:14之间的数据是第一组 02:15和02:29是第二组。 02:30和02:44 .....

我需要每个小组的分析。

必须使用forwhile使用15.minutes time helper,但我无法使其正常工作。

如何处理这些?

谢谢。

编辑:

数组结构如下:

ras_date                   tv1_rating              tv2_rating             tv3_rating
------------------------------------------------------------------------------------
2013-03-04 02:00:00 UTC   |  2.184922836     |   2.278915283     |     2.278915283
2013-03-04 02:01:00 UTC   |  2.194639015     |   3.278915283     |     1.278915283
2013-03-04 02:02:00 UTC   |  0.234917032     |   4.278915283     |     0.278915283
2013-03-04 02:03:00 UTC   |  2.278915283     |   1.278915283     |     2.278915283
..
.

根据ras_date,我想计算每个电视台的评分平均值为15分钟。

好吧,使用for和while只是猜测我的。欢迎任何类型的解决方案。谢谢。

编辑-2:

[#<DataFile id: 48009, timeband: \"02:00\", ras_date: \"2013-03-04 02:00:00\", created_at: \"2013-03-05 18:45:16\", updated_at: \"2013-03-05 18:45:16\", tv1_rtg: 0.231275974, tv1_shr: 3.459938790606675, tv2_rtg: 0.465407082, tv2_shr: 6.9625910058208715, tv4_rtg: 0.024855499, tv4_shr: 0.3718436621954748, tv5_rtg: 0.355105523, tv5_shr: 5.3124557321564705, tv3_rtg: 0.306065103, tv3_shr: 4.578800400255703, tv6_rtg: 0.425388078, tv6_shr: 6.363898016202141, tv8_rtg: 0.184050299, tv8_shr: 2.7534324379620037, tv7_rtg: 0.13351472, tv7_shr: 1.9974092027604597, tv8_rtg: 0.104982397, tv8_shr: 1.5705594551346256, ttv_rtg: 6.684394956, ttv_shr: 100.0, tv9_shr: 3.8946589139877266, tv9_rtg: 0.260334384>, #<DataFile id: 48010, timeband: \"02:01\", ras_date: \"2013-03-04 02:01:00\", created_at: \"2013-03-05 18:45:16\", updated_at: \"2013-03-05 18:45:16\", tv1_rtg: 0.111862045, tv1_shr: 1.6818552137556582, tv2_rtg: 0.464504362, tv2_shr: 6.983861979654901, tv4_rtg: 0.057792275, tv4_shr: 0.8689116940741676, tv5_rtg: 0.353541524, tv5_shr: 5.315526418442655, tv3_rtg: 0.315364133, tv3_shr: 4.741526147833099, tv6_rtg: 0.463173951, tv6_shr: 6.963859138863031, tv8_rtg: 0.188181065, tv8_shr: 2.8293180703101073, tv7_rtg: 0.148338388, tv7_shr: 2.2302800852416897, tv8_rtg: 0.112267205, tv8_shr: 1.6879468282832242, ttv_rtg: 6.651110279, ttv_shr: 100.0, tv9_shr: 3.673313247735431, tv9_rtg: 0.244316115>, #<DataFile id: 48011, timeband: \"02:02\", ras_date: \"2013-03-04 02:02:00\", created_at: \"2013-03-05 18:45:16\", updated_at: \"2013-03-05 18:45:16\", tv1_rtg: 0.096118706, tv1_shr: 1.4904838004557073, tv2_rtg: 0.482073193, tv2_shr: 7.475363690398179, tv4_rtg: 0.045212074, tv4_shr: 0.7010900030427445, tv5_rtg: 0.367055659, tv5_shr: 5.691821460903709, tv3_rtg: 0.336406586, tv3_shr: 5.2165555245782205, tv6_rtg: 0.463173951, tv6_shr: 7.18229884158621, tv8_rtg: 0.175622569, tv8_shr: 2.72332623879596, tv7_rtg: 0.13351472, tv7_shr: 2.0703725171079563, tv8_rtg: 0.109862708, tv8_shr: 1.7036078965544506, ttv_rtg: 6.448825943, ttv_shr: 100.0, tv9_shr: 4.214133803611018, tv9_rtg: 0.271762154>, #<DataFile id: 48012, timeband: \"02:03\", ras_date: \"2013-03-04 02:03:00\", created_at: \"2013-03-05 18:45:16\", updated_at: \"2013-03-05 18:45:16\", tv1_rtg: 0.111568925, tv1_shr: 1.7336392363465083, tv2_rtg: 0.589141334, tv2_shr: 9.154507246313642, tv4_rtg: 0.100518614, tv4_shr: 1.5619314537051374, tv5_rtg: 0.402849844, tv5_shr: 6.259774358446762, tv3_rtg: 0.328333577, tv3_shr: 5.101886315541693, tv6_rtg: 0.43495935, tv6_shr: 6.758715254949115, tv8_rtg: 0.175622569, tv8_shr: 2.7289514208940524, tv7_rtg: 0.13351472, tv7_shr: 2.0746489869093736, tv8_rtg: 0.102741203, tv8_shr: 1.5964676607777801, ttv_rtg: 6.435532991, ttv_shr: 100.0, tv9_shr: 1.7713521655381412, tv9_rtg: 0.113995953>]

编辑-3:

我的数组文件如上(参见edit-2)。

当我尝试:

d = DataFile.all
d.each_slice(15) { |v| puts v.inject(0.0) { |sum, el| sum + el } /  v.size }

我收到了这个错误:

TypeError: DataFile can't be coerced into Float
    from (irb):31:in `+'
    from (irb):31:in `block (2 levels) in irb_binding'
    from (irb):31:in `each'
    from (irb):31:in `inject'
    from (irb):31:in `block in irb_binding'
    from (irb):31:in `each'
    from (irb):31:in `each_slice'
    from (irb):31

2 个答案:

答案 0 :(得分:1)

您已经有slice 15所需的值数组,并找到了中位数。忘了几分钟,然后:

vals.each_slice(15) { |v|
 puts v.inject(0.0) { |sum, el| sum + el } / v.size
}
这里的

each_slice方法是将一个数组切片15个elemetns。 inject正在迭代元素并根据代码块聚合sum中的值。代码块必须返回要聚合的值。希望它有所帮助。

如果您在数组中有复杂的值(例如Hash),那么您要sum想要总结的内容:

vals.each_slice(15) { |v|
  puts v.inject(0.0) { |sum, el| sum + el.tv1_rtg } / v.size
}

答案 1 :(得分:1)

将时间分为0到14分钟到15分钟组,时间分为15到29分到30分钟组,依此类推。对于每个组,它需要平均值。

这是一个有效的代码:

require 'date'
a = Hash.new
d = DataFile.all
d.each do |dd|
        a[dd.ras_date.to_s] = [dd.tv1_rtg, dd.tv2_rtg, dd.tv3_rtg, dd.tv4_rtg, dd.tv5_rtg, dd.tv6_rtg, dd.tv7_rtg, dd.tv8_rtg, dd.tv9_rtg, dd.ttv_rtg]
end

number_of_ratings = 10

b = Hash.new
c = Hash.new
a.each do |k,value|
        aa = DateTime.parse(k)
        k_round = (aa + Rational(((aa.min/15+1)*15-aa.min)*60-aa.sec,86400)).to_s
        if b.has_key?(k_round)
        else
                b[k_round] = Array.new(number_of_ratings){|i| 0}
                c[k_round] = 0
        end
        b[k_round] = b[k_round].zip(value).map{|pair| pair.reduce(&:+) }
        c[k_round] = c[k_round]+1
end
b.each do |key,value|
        if c[key]!=0
                n_array = Array.new(number_of_ratings){|i| c[key]}
                b[key] = b[key].zip(n_array).map{|pair| pair.reduce(&:/) }
                p "#{key} => #{b[key]}"
        end
end

修改

k_round = (aa + Rational(((aa.min/15+1)*15-aa.min)*60-aa.sec,86400)).to_s

aa是一个DateTime对象。

Rational是一个在数学中产生有理数的函数。理性(3,4)= 3/4

to_s是一个将数字(float,int,任意数字)转换为字符串的函数。

在一天中,有86400秒。

此表达式((aa.min/15+1)*15-aa.min)*60-aa.sec将分钟部分向上舍入为15的整数倍,并将第二部分重置为0。

将34.45四舍五入为15的倍数的简单示例是:

34/15 = 2.26,最多为3.现在,将它加倍15,这使得它为45。

第二部分时间是45.因此,将其重置为零。

因此,我们以小时为单位添加时间,因此我们使用Rational函数将秒数转换为小时数。

您可以使用5分钟,30分钟和60分钟,如:

integral_multiple = 5
k_round = (aa + Rational(((aa.min/integral_multiple+1)*integral_multiple-aa.min)*60-aa.sec,86400)).to_s