2016-02-09 1 views
0

Я думаю, что определение проблемы довольно просто, но я ищу решение, подходящее для очень большого набора данных (20+ миллионов).Python: усреднение данных таймсеров в ящиках заданной продолжительности

У меня есть два списка: stamps, содержащие N временные метки и values содержащие N скалярные значения.

Я могу легко построить эти данные, чтобы иметь график времени.

Теперь я хотел бы рассчитать среднее значение values, выровненное в 1-минутный лоток (обычно у меня 50 значений в минуту, но бывает, что некоторые пустые). Пустые значения, приводящие к пустым ячейкам, должны сделать среднее значение этого бина равным нулю.

Как я мог эффективно сделать это с минимальным кодом?

+0

Я попытаюсь опубликовать начальное частичное решение в вопросе как можно скорее. –

+0

Что вы хотите сделать с пустыми значениями? Относитесь к ним как к 0 и все еще в среднем более 50? Или среднее значение (num per bin - num empty)? – Simon

+0

Пустые значения, приводящие к пустым ячейкам, должны сделать среднее значение этого бункера равным нулю. –

ответ

1
minute_bins = {} 
averages = {} 

for i in range(len(values)): 

    # Integer division 
    minute = stamps[i] // 60 

    if minute in minute_bins: 
     minute_bins[minute].append(values[i]) 
    else: 
     minute_bins[minute] = [values[i]] 

for key in minute_bins: 
    minute_values = minute_bins[key] 
    averages[key] = float(sum(minute_values))/len(minute_values) 

Предполагая, что у вас есть ваши штампы времени в виде числа. Я использовал time.time() для проверки моего кода, но в любом формате, где должны быть две метки времени на 1 секунду друг от друга на 1.0.

+0

У меня есть timestamp как 'datetime.datetime' объекты, поэтому' stamp.timestamp() 'должен делать. Большое спасибо! –

0

Седрик. Поскольку ваш набор данных настолько велик, я думаю, вам нужно решение, которое не требует чтения всех значений в списке, а затем последующего усреднения. Я хотел бы использовать простой класс усреднения, который вычисляет скользящее среднее, что-то вроде этого:

import collections 

class averager(object): 
    def __init__(self): 
     self.avg = 0 
     self.n = 0 
    def add(self, x): 
     self.avg = ((self.avg * self.n) + x)/(self.n + 1) 
     self.n += 1 

d = collections.defaultdict(averager) 

for timestamp, value in zip(stamps, values): 
    d[timestamp // 60].add(value) 

for k in sorted(list(d.keys())): 
    print(k, d[k].avg, sep="\t") 

Ваша проблема также, кажется, поддается параллельной обработке - разделить набор данных на куски, вычислять средние значения по каждой порции, работающих параллельно, а затем усредняют средние значения.

Надеюсь, это поможет.

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