得到一个包含时间值的表,以毫秒为单位分辨率。是否有一种快速方法可以平均在一秒钟内发生所有值(操作后)?
输入表格
时间,价值
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
输出表格
时间,值
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 :(得分: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]
其他计算也是类似的。