csv - ruby - averaging values to a second -


got table contains values against time in milliseconds resolution. there quick way average values (after operation) occurring in second ?

input table

time , value

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

output table

time,value

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`

i'm reading input file csv csv::table, each row can read row[i] = csv[i] , row[i]['time'] , row[i]['value'] available - helpful ideas on how manipulate average.

this 1 way it, assuming array sorted time, in example.

code

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 

if a not sorted, first sort on first element:

a.sort_by(&:first) 

example

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]]  

explanation

the steps:

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

convert enumerator array see it's contents:

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 e) 

you can think of f "compound enumerator". pass first element of f block , assign block variables:

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 

so first element of f mapped to:

["00:54:08", 255.0] 

the other calculations performed similarly.


Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -