Generate features for TimeSeries
Project description
Chrono Features
A Python library for efficient time series feature generation with support for various window types and optimized calculations.
Installation
pip install chrono-features
Overview
Chrono Features is a library designed to simplify the process of generating features from time series data. It provides:
- Support for multiple window types (expanding, rolling, dynamic)
- Optimized calculations for better performance
- A consistent API for all feature generators
- Integration with polars DataFrames
import polars as pl
from chrono_features import TSDataset, WindowType
from chrono_features.features import Max, Median, Sum, Std
# Create a sample dataset
data = pl.DataFrame(
{
"id": [1, 1, 1, 2, 2, 2],
"timestamp": [1, 2, 3, 1, 2, 3],
"value": [1, 2, 3, 4, 5, 6],
}
)
# Create a TSDataset
dataset = TSDataset(data, id_column_name="id", ts_column_name="timestamp")
# Create a feature transformer
max_transformer = Max(
columns="value",
window_types=WindowType.EXPANDING(),
)
# Apply the transformation
transformed_dataset = max_transformer.transform(dataset)
# View the result
print(transformed_dataset.data)
shape: (6, 4)
┌─────┬───────────┬───────┬─────────────────────┐
│ id ┆ timestamp ┆ value ┆ value_max_expanding │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ f64 │
╞═════╪═══════════╪═══════╪═════════════════════╡
│ 1 ┆ 1 ┆ 1 ┆ 1.0 │
│ 1 ┆ 2 ┆ 2 ┆ 2.0 │
│ 1 ┆ 3 ┆ 3 ┆ 3.0 │
│ 2 ┆ 1 ┆ 4 ┆ 4.0 │
│ 2 ┆ 2 ┆ 5 ┆ 5.0 │
│ 2 ┆ 3 ┆ 6 ┆ 6.0 │
└─────┴───────────┴───────┴─────────────────────┘
Supported Transformers
The following table lists all available transformers in the chrono_features.features package:
| Transformer | Description | Main Parameters |
|---|---|---|
Max |
Calculates maximum value in window | columns, window_types |
Min |
Calculates minimum value in window | columns, window_types |
Sum |
Calculates sum of values in window | columns, window_types, use_prefix_sum_optimization |
Mean |
Calculates average of values in window | columns, window_types |
Std |
Calculates standard deviation in window | columns, window_types |
Median |
Calculates median value in window | columns, window_types |
SimpleMovingAverage |
Calculates simple moving average | columns, window_size, only_full_window |
WeightedMovingAverage |
Calculates weighted moving average | columns, window_size, weights, only_full_window |
Core Concepts
TSDataset
The TSDataset class is a wrapper around a polars DataFrame that provides additional functionality for time series data
import polars as pl
from chrono_features import TSDataset
df = pl.DataFrame({
"id": [1, 1, 1, 2, 2, 2],
"timestamp": [1, 2, 3, 1, 2, 3],
"value": [5, 3, 4, 10, 2, 3],
})
# Create a TSDataset from a polars DataFrame
dataset = TSDataset(
data=df,
id_column_name="id", # Column containing entity identifiers
ts_column_name="timestamp" # Column containing timestamps
)
# Add a new feature
dataset.add_feature("new_feature", [1, 2, 3, 4, 5, 6])
Window Types
The library supports different types of windows for feature calculation. Window types determine how data points are grouped for feature calculation:
from chrono_features import WindowType
# Expanding window (includes all previous values)
expanding_window = WindowType.EXPANDING()
# For each timestamp, includes all data points from the beginning up to the current timestamp
# Example: For timestamps [1, 2, 3], windows would be [1], [1, 2], [1, 2, 3]
# Rolling window (includes only the last N values)
rolling_window = WindowType.ROLLING(size=10) # Window of size 10
# For each timestamp, includes at most N previous data points
# Example with size=2: For timestamps [1, 2, 3], windows would be [1], [1, 2], [2, 3]
# Rolling window with only full windows
rolling_window_full = WindowType.ROLLING(size=10, only_full_window=True)
# Only calculates features when the window has exactly N data points
# Example with size=2: For timestamps [1, 2, 3], windows would be [NaN], [1, 2], [2, 3]
# Dynamic window (window size varies based on a column)
dynamic_window = WindowType.DYNAMIC(len_column_name="window_len")
# Window size is determined by values in the specified column
# Example: If window_len column has values [1, 2, 1], windows would include
# the last 1, 2, and 1 data points respectively
Window Type Combinations
You can use multiple window types for a single feature generator:
from chrono_features import WindowType
from chrono_features.features import Max
# Using multiple window types in a single transformer
max_transformer = Max(
columns="value",
window_types=[
WindowType.EXPANDING(),
WindowType.ROLLING(size=5),
WindowType.ROLLING(size=10),
]
)
# This will create three output columns:
# - value_max_expanding
# - value_max_rolling_5
# - value_max_rolling_10
Window Type Behavior by ID
Windows are calculated separately for each unique ID in your dataset:
# For a dataset with:
# id=1, timestamp=[1, 2, 3], value=[10, 20, 30]
# id=2, timestamp=[1, 2, 3], value=[40, 50, 60]
# With WindowType.EXPANDING():
# For id=1: windows are [10], [10, 20], [10, 20, 30]
# For id=2: windows are [40], [40, 50], [40, 50, 60]
# With WindowType.ROLLING(size=2):
# For id=1: windows are [10], [10, 20], [20, 30]
# For id=2: windows are [40], [40, 50], [50, 60]
Transformation Pipeline
You can combine multiple transformers into a pipeline for more efficient processing:
import pandas as pd
import polars as pl
from chrono_features import TSDataset, WindowType
from chrono_features.features import Sum, Median, Max
from chrono_features.transformation_pipeline import TransformationPipeline
dataset = TSDataset(
data=pl.DataFrame({
"id": [1, 1, 1, 2, 2, 2],
"timestamp": [1, 2, 3, 1, 2, 3],
"value": [1, 2, 3, 4, 5, 6],
}),
id_column_name="id",
ts_column_name="timestamp"
)
# Create a pipeline with multiple transformers
pipeline = TransformationPipeline(
[
Sum(columns="value", window_types=WindowType.EXPANDING()),
Median(columns="value", window_types=WindowType.ROLLING(size=10)),
Max(columns="value", window_types=WindowType.EXPANDING()),
],
verbose=True # Print progress information
)
# Apply the pipeline to a TSDataset
transformed_dataset = pipeline.fit_transform(dataset)
# Or apply directly to a polars DataFrame
pl_df = pl.DataFrame({
"id": [1, 1, 1, 2, 2, 2],
"timestamp": [1, 2, 3, 1, 2, 3],
"value": [1, 2, 3, 4, 5, 6],
})
# Transform the polars DataFrame directly
transformed_pl_df = pipeline.fit_transform(
pl_df,
id_column_name="id",
ts_column_name="timestamp"
)
# Or apply to a pandas DataFrame
pd_df = pd.DataFrame({
"id": [1, 1, 1, 2, 2, 2],
"timestamp": [1, 2, 3, 1, 2, 3],
"value": [1, 2, 3, 4, 5, 6],
})
# Transform the pandas DataFrame directly
transformed_pd_df = pipeline.fit_transform(
pd_df,
id_column_name="id",
ts_column_name="timestamp"
)
Examples
Calculating Multiple Features
import polars as pl
from chrono_features import TSDataset, WindowType
from chrono_features.features import Max, Median, Sum, Std
from chrono_features.transformation_pipeline import TransformationPipeline
# Create a sample dataset
data = pl.DataFrame(
{
"id": [1, 1, 1, 2, 2, 2],
"timestamp": [1, 2, 3, 1, 2, 3],
"price": [10, 12, 15, 20, 18, 22],
"volume": [100, 120, 150, 200, 180, 220],
}
)
# Create a TSDataset
dataset = TSDataset(data, id_column_name="id", ts_column_name="timestamp")
# Create transformers for different columns
max_price = Max(columns="price", window_types=WindowType.EXPANDING())
sum_volume = Sum(columns="volume", window_types=WindowType.EXPANDING())
median_price = Median(columns="price", window_types=WindowType.ROLLING(size=2))
std_volume = Std(columns="volume", window_types=WindowType.ROLLING(size=2))
# Create a pipeline with multiple transformers
pipeline = TransformationPipeline(
[
max_price,
sum_volume,
median_price,
std_volume,
],
verbose=True # Print progress information
)
# Apply the pipeline
transformed_dataset = pipeline.fit_transform(dataset)
# View the result
print(transformed_dataset.data)
Applying transformation 1/4: MaxWithOptimization...
Added columns: ['price_max_expanding']
Dataset shape: 6 rows, 5 columns
Applying transformation 2/4: Sum...
Added columns: ['price_max_expanding', 'volume_sum_expanding']
Dataset shape: 6 rows, 6 columns
Applying transformation 3/4: Median...
Added columns: ['price_max_expanding', 'price_median_rolling_2', 'volume_sum_expanding']
Dataset shape: 6 rows, 7 columns
Applying transformation 4/4: StdWithoutOptimization...
Added columns: ['price_max_expanding', 'price_median_rolling_2', 'volume_std_rolling_2', 'volume_sum_expanding']
Dataset shape: 6 rows, 8 columns
shape: (6, 8)
┌─────┬───────────┬───────┬────────┬─────────────────────┬──────────────────────┬────────────────────────┬──────────────────────┐
│ id ┆ timestamp ┆ price ┆ volume ┆ price_max_expanding ┆ volume_sum_expanding ┆ price_median_rolling_2 ┆ volume_std_rolling_2 │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ f64 ┆ f64 ┆ f32 ┆ f32 │
╞═════╪═══════════╪═══════╪════════╪═════════════════════╪══════════════════════╪════════════════════════╪══════════════════════╡
│ 1 ┆ 1 ┆ 10 ┆ 100 ┆ 10.0 ┆ 100.0 ┆ NaN ┆ NaN │
│ 1 ┆ 2 ┆ 12 ┆ 120 ┆ 12.0 ┆ 220.0 ┆ 11.0 ┆ 10.0 │
│ 1 ┆ 3 ┆ 15 ┆ 150 ┆ 15.0 ┆ 370.0 ┆ 13.5 ┆ 15.0 │
│ 2 ┆ 1 ┆ 20 ┆ 200 ┆ 20.0 ┆ 200.0 ┆ NaN ┆ NaN │
│ 2 ┆ 2 ┆ 18 ┆ 180 ┆ 20.0 ┆ 380.0 ┆ 19.0 ┆ 10.0 │
│ 2 ┆ 3 ┆ 22 ┆ 220 ┆ 22.0 ┆ 600.0 ┆ 20.0 ┆ 20.0 │
└─────┴───────────┴───────┴────────┴─────────────────────┴──────────────────────┴────────────────────────┴──────────────────────┘
Using Dynamic Windows
import polars as pl
from chrono_features import TSDataset, WindowType
from chrono_features.features import Max
# Create a sample dataset
data = pl.DataFrame(
{
"id": [1, 1, 1, 2, 2, 2],
"timestamp": [1, 2, 3, 1, 2, 3],
"value": [1, 2, 3, 4, 5, 6],
"window_len": [1, 2, 3, 1, 2, 3], # Dynamic window lengths
}
)
# Create a TSDataset
dataset = TSDataset(data, id_column_name="id", ts_column_name="timestamp")
# Create a transformer with dynamic window
max_transformer = Max(
columns="value",
window_types=WindowType.DYNAMIC(len_column_name="window_len"),
)
# Apply the transformation
transformed_dataset = max_transformer.transform(dataset)
# View the result
print(transformed_dataset.data)
shape: (6, 5)
┌─────┬───────────┬───────┬────────────┬─────────────────────────────────┐
│ id ┆ timestamp ┆ value ┆ window_len ┆ value_max_dynamic_based_on_win… │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ f32 │
╞═════╪═══════════╪═══════╪════════════╪═════════════════════════════════╡
│ 1 ┆ 1 ┆ 1 ┆ 1 ┆ 1.0 │
│ 1 ┆ 2 ┆ 2 ┆ 2 ┆ 2.0 │
│ 1 ┆ 3 ┆ 3 ┆ 3 ┆ 3.0 │
│ 2 ┆ 1 ┆ 4 ┆ 1 ┆ 4.0 │
│ 2 ┆ 2 ┆ 5 ┆ 2 ┆ 5.0 │
│ 2 ┆ 3 ┆ 6 ┆ 3 ┆ 6.0 │
└─────┴───────────┴───────┴────────────┴─────────────────────────────────┘
License
This project is licensed under the terms of the LICENSE file (MIT License) included in the repository.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chrono_features-0.0.11.tar.gz.
File metadata
- Download URL: chrono_features-0.0.11.tar.gz
- Upload date:
- Size: 26.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1070fef32f3a20df8a38dbde05187ad8bc8a7308f1a1f41fa8250b231c5d0ffc
|
|
| MD5 |
6c2f4a461cfef263dfc7ea75785184b7
|
|
| BLAKE2b-256 |
b59930ae8bac3d9ec25d1575a787d5a7c9ea55137c1864a2b48ea62750b0e14f
|
File details
Details for the file chrono_features-0.0.11-py3-none-any.whl.
File metadata
- Download URL: chrono_features-0.0.11-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4dadbd2bdb321ba2b399b859184ee58c73a9b04d189243de4900784c71127413
|
|
| MD5 |
50bceed0731f18a72b15cf9579f64d08
|
|
| BLAKE2b-256 |
5f7836625f923ed09305c3001d1c4321afd735254c221e49f95e784263a29365
|