2015-04-01 5 views
0

Получил таблицу, содержащую значения против времени в миллисекундах. Есть ли быстрый способ усреднить все значения (после операции), возникающие за секунду?ruby ​​- усреднение значений до секунды

входной таблицы

времени, значение

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

Значит, вы хотите усреднить значения, соответствующие> 00: 54: 08.00, но <00: 54: 09.000? Почему это похоже на то, что вы усредняете, возводя квадрат своих значений перед их добавлением и делением на количество операндов? Разве это не должно быть (14 + 13 + 20)/3'? Какой у вас код до сих пор? – Beartech

+0

Цель состоит в том, чтобы получить среднее значение в секунду для значений во входной таблице. В идеале, все значения от '00: 54: 07.501' до' 00: 54: 08.499', попадают в ведро в секунду для '00: 54: 08.000'. Это не только среднее значение, но операция выполняется для отдельных значений перед усреднением. Я использовал «квадрат», чтобы просто проиллюстрировать этот аспект. – user3206440

ответ

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] 

Остальные расчеты выполняются аналогично.

Смежные вопросы