Time Series#

[1]:
# Import to be able to import python package from src
import sys
sys.path.insert(0, '../src')
[2]:
print(sys.path)
['../src', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '', '/home/benjy/.cache/pypoetry/virtualenvs/ontime-2OQVvbNf-py3.10/lib/python3.10/site-packages', '/home/benjy/projects_dev/ontime/src']
[3]:
import pandas as pd
import numpy as np
import ontime as on

Generation of random time series#

[4]:
ts = on.generators.random_walk().generate(start=pd.Timestamp('2022-01-01'), end=pd.Timestamp('2022-12-31'))
[5]:
ts[0:5]
[5]:
<TimeSeries (DataArray) (time: 5, component: 1, sample: 1)> Size: 40B
array([[[0.18681962]],

       [[1.38205429]],

       [[1.85408518]],

       [[1.01011117]],

       [[0.37180233]]])
Coordinates:
  * time       (time) datetime64[ns] 40B 2022-01-01 2022-01-02 ... 2022-01-05
  * component  (component) object 8B 'random_walk'
Dimensions without coordinates: sample
Attributes:
    static_covariates:  None
    hierarchy:          None

Use TimeSeries object#

[7]:
ts.plot()
[7]:

Custom Class Creation#

Create custom detector#

[8]:
from ontime.core.detection.abstract_detector import AbstractDetector

class MyAE(AbstractDetector):

    def __init__(self):
        super().__init__()

    def detect(self, ts):
        print('I detected')

Load custom detector in OnTime

[9]:
on.detectors.get_all()
[9]:
['threshold', 'quantile']
[10]:
on.detectors.load('my_ae', MyAE)
[11]:
on.detectors.get_all()
[11]:
['threshold', 'quantile', 'my_ae']
[12]:
on.detectors.my_ae().detect(ts)
I detected

Data Loading Helpers#

From Darts to onTime#

You can convert a timeseries from Darts’ TimeSeries object type to ontime’s TimeSeries type.

[13]:
from darts import datasets as dd

dartsAirPassengers = dd.AirPassengersDataset().load()
print(type(dartsAirPassengers))
dartsAirPassengers.head()
<class 'darts.timeseries.TimeSeries'>
[13]:
<TimeSeries (DataArray) (Month: 5, component: 1, sample: 1)> Size: 40B
array([[[112.]],

       [[118.]],

       [[132.]],

       [[129.]],

       [[121.]]])
Coordinates:
  * Month      (Month) datetime64[ns] 40B 1949-01-01 1949-02-01 ... 1949-05-01
  * component  (component) object 8B '#Passengers'
Dimensions without coordinates: sample
Attributes:
    static_covariates:  None
    hierarchy:          None
[14]:
ontimeAirPassengers = on.TimeSeries.from_darts(dartsAirPassengers)
print(type(ontimeAirPassengers))
ontimeAirPassengers.head()
<class 'ontime.core.time_series.time_series.TimeSeries'>
[14]:
<TimeSeries (DataArray) (Month: 5, component: 1, sample: 1)> Size: 40B
array([[[112.]],

       [[118.]],

       [[132.]],

       [[129.]],

       [[121.]]])
Coordinates:
  * Month      (Month) datetime64[ns] 40B 1949-01-01 1949-02-01 ... 1949-05-01
  * component  (component) object 8B '#Passengers'
Dimensions without coordinates: sample
Attributes:
    static_covariates:  None
    hierarchy:          None

From Pandas to onTime#

You can convert a Pandas DataFrame to onTime’s TimeSeries format, provided the DataFrame’s index is time-based.

[23]:
from sklearn.datasets import fetch_openml

pandasAmd = fetch_openml("AMD-Stock-Prices-Historical-Data", version=1, as_frame=True, parser="pandas").frame
print(type(pandasAmd))
# set index to be compliant with TimeEval's canonical format
pandasAmd.index= pandasAmd['Date'].astype('datetime64[ns]')
del pandasAmd['Date']
pandasAmd = pandasAmd.rename_axis("time")
pandasAmd.head()
<class 'pandas.core.frame.DataFrame'>
[23]:
Open High Low Close Adj_Close Volume
time
1980-03-17 0.0 3.302083 3.125000 3.145833 3.145833 219600
1980-03-18 0.0 3.125000 2.937500 3.031250 3.031250 727200
1980-03-19 0.0 3.083333 3.020833 3.041667 3.041667 295200
1980-03-20 0.0 3.062500 3.010417 3.010417 3.010417 159600
1980-03-21 0.0 3.020833 2.906250 2.916667 2.916667 130800
[24]:
ontimeAmd = on.TimeSeries.from_pandas(pandasAmd, freq='D')
ontimeAmd.head()
[24]:
<TimeSeries (DataArray) (time: 5, component: 6, sample: 1)> Size: 240B
array([[[0.00000000e+00],
        [3.30208302e+00],
        [3.12500000e+00],
        [3.14583302e+00],
        [3.14583302e+00],
        [2.19600000e+05]],

       [[0.00000000e+00],
        [3.12500000e+00],
        [2.93750000e+00],
        [3.03125000e+00],
        [3.03125000e+00],
        [7.27200000e+05]],

       [[0.00000000e+00],
        [3.08333302e+00],
        [3.02083302e+00],
        [3.04166698e+00],
        [3.04166698e+00],
        [2.95200000e+05]],

       [[0.00000000e+00],
        [3.06250000e+00],
        [3.01041698e+00],
        [3.01041698e+00],
        [3.01041698e+00],
        [1.59600000e+05]],

       [[0.00000000e+00],
        [3.02083302e+00],
        [2.90625000e+00],
        [2.91666698e+00],
        [2.91666698e+00],
        [1.30800000e+05]]])
Coordinates:
  * time       (time) datetime64[ns] 40B 1980-03-17 1980-03-18 ... 1980-03-21
  * component  (component) object 48B 'Open' 'High' ... 'Adj_Close' 'Volume'
Dimensions without coordinates: sample
Attributes:
    static_covariates:  None
    hierarchy:          None
[25]:
ontimeAmd.plot()
[25]:

CSV to onTime#

You can convert data from a CSV file to onTime’s TimeSeries format, provided the index is time-based and correctly formatted.

[26]:
# let's generate some sample data
ts = on.generators.random_walk().generate(start=pd.Timestamp('2022-01-01'), end=pd.Timestamp('2022-12-31'))
ts.pd_dataframe().to_csv('sample_series.csv')

# load that sample data
ts = on.TimeSeries.from_csv('sample_series.csv', index_col='time')
ts.plot()
[26]:

Data (e.g. Numpy) to onTime#

You can assemble a TimeSeries if you have a data table and column names, provided the index is time-based and correctly formatted.

[27]:
# generate some data
from datetime import datetime
data = np.random.rand(200,3)
index = pd.date_range(datetime.today(), periods=200).tolist()
columns = ['col1', 'col2', 'col3']
[28]:
# assemble into a timeseries
ts = on.TimeSeries.from_data(data, index = index, columns = columns)
ts.plot()
[28]:
[ ]: