2015-04-01 88 views
0

得到一个表,其中包含值以毫秒为单位的时间分辨率。是否有快速的方法来平均所有的值(在一个操作之后)发生在第二个?红宝石 - 平均值为第二个

输入表

时间,值

00:54:08.349,14

00:54:08.349,13

00:54:08.449,20

00:54:09.349,15 15

00:54:09.628,21

00:54:10.679,13

00:54:10.839,12

输出表

时间,值

00 :54:08.000,255(14^2 + 13^2 + 20^2)/ 3

00:54:09.000,333(15^2 + 21^2)/ 2

00:54:10.000,156.5(13^2 + 12^2)/ 2`

我从csv读取输入文件作为CSV::table,所以每一行可以读作row[i] = csv[i]row[i]['time']row[i]['value']可用 - 将有助于获得有关如何操纵它以获得平均值的想法。

+0

所以你想平均值> 00:54:08.00对应但是<00:54:09.000?为什么它看起来像是通过平方值来平均值,然后再除以操作数的数量?它不应该是(14 + 13 + 20)/ 3'吗?你目前有什么代码? – Beartech 2015-04-01 04:15:51

+0

目标是获得输入表中每秒平均值。理想情况下,从'00:54:07.501'到'00:54:08.499'的所有值都落入'00:54:08.000'的每秒桶中。这不仅仅是平均值 - 而是在平均之前对各个值进行操作。我用'方形'来说明这个方面。 – user3206440 2015-04-01 04:41:23

回答

1

这是实现它的一种方法,假设数组按照时间排序,就像它在示例中一样。

代码

def avg_of_squares(a) 
    a.chunk { |t,v| t[0,8] }.map { |t,v| 
    [t[0,8], v.reduce(0) { |tot,(_,x)| tot + x*x }/(v.size.to_f)] } 
end 

如果a不排序,在第一元件上的第一排序它:

a.sort_by(&:first) 

a = [["00:54:08.349", 14], 
    ["00:54:08.349", 13], 
    ["00:54:08.449", 20], 
    ["00:54:09.349", 15], 
    ["00:54:09.628", 21], 
    ["00:54:10.679", 13], 
    ["00:54:10.839", 12]] 

avg_of_squares(a) 
    #=> [["00:54:08", 255.0], ["00:54:09", 333.0], ["00:54:10", 156.5]] 

个说明

步骤:

e = a.chunk { |t,v| t[0,8] } 
    #=> #<Enumerator: #<Enumerator::Generator:0x007fbaac08a2f0>:each> 

转换的枚举到一个数组中看到它的内容:

e.to_a 
    #=> [["00:54:08", [["00:54:08.349", 14], ["00:54:08.349", 13], 
    #     ["00:54:08.449", 20]]], 
    # ["00:54:09", [["00:54:09.349", 15], ["00:54:09.628", 21]]], 
    # ["00:54:10", [["00:54:10.679", 13], ["00:54:10.839", 12]]]] 

f = e.map 
    #=> #<Enumerator: #<Enumerator: # 
    # <Enumerator::Generator:0x007fbaac08a2f0>:each>:map> 
f.to_a 
    # (same as for e) 

你能想到的f “化合物枚举”。传递的f第一元件到块和分配块变量:

t,v = f.next 
    #=> ["00:54:08", [["00:54:08.349", 14], ["00:54:08.349", 13], 
    # ["00:54:08.449", 20]]] 
t 
    #=> "00:54:08" 
v 
    #=> [["00:54:08.349", 14], ["00:54:08.349", 13], ["00:54:08.449", 20]] 
g = v.reduce(0) { |tot,(_,x)|tot + x*x }/(v.size.to_f) 
    #=> 255.0 

这样的f第一元件被映射到:

["00:54:08", 255.0] 

的其他计算类似地执行。