55 lines
1.9 KiB
Python
55 lines
1.9 KiB
Python
from datetime import datetime
|
|
from datetime import timezone
|
|
import numpy
|
|
|
|
|
|
class TimeSeriesAccumulator:
|
|
def __init__(self, start_time, end_time, n_bins, alignment=None):
|
|
self.start_time = start_time
|
|
self.start_timestamp = start_time.replace(
|
|
tzinfo=timezone.utc).timestamp()
|
|
self.end_time = end_time
|
|
self.end_timestamp = end_time.replace(tzinfo=timezone.utc).timestamp()
|
|
self.n_bins = n_bins
|
|
|
|
if alignment:
|
|
self.start_timestamp = (
|
|
self.start_timestamp//alignment) * alignment
|
|
self.end_timestamp = (self.end_timestamp//alignment) * alignment
|
|
|
|
self.bin_time = (self.end_timestamp -
|
|
self.start_timestamp)/self.n_bins
|
|
self.data = [[] for _ in range(n_bins)]
|
|
|
|
def add(self, time, value):
|
|
timestamp = time.replace(tzinfo=timezone.utc).timestamp()
|
|
if timestamp < self.start_timestamp or timestamp > self.end_timestamp:
|
|
return
|
|
idx = int((timestamp - self.start_timestamp)/self.bin_time)
|
|
self.data[idx].append(value)
|
|
|
|
def get_f(self, f, initial=0):
|
|
prev = initial
|
|
result = []
|
|
for i in self.data:
|
|
new = f(i)
|
|
if numpy.isnan(new):
|
|
result.append(prev)
|
|
else:
|
|
result.append(new)
|
|
prev = new
|
|
return result
|
|
|
|
def get_ts(self):
|
|
return [datetime.utcfromtimestamp(int(self.start_timestamp+(i+1)*self.bin_time)) for i in range(self.n_bins)]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
tsa = TimeSeriesAccumulator(start_time=datetime(
|
|
2020, 7, 27, 23, 0, 33), end_time=datetime(2020, 7, 28, 0, 0, 43), n_bins=2, alignment=5)
|
|
tsa.add(datetime(2020, 7, 27, 23, 15, 0), 1)
|
|
tsa.add(datetime(2020, 7, 27, 23, 45, 0), 2)
|
|
tsa.add(datetime(2020, 7, 27, 22, 45, 0), 3)
|
|
print(tsa.get_ts())
|
|
print(tsa.get_f(lambda x: sum(x)))
|