API Reference

Contents

API Reference#

This page documents the tsam API including the new function-based API and the legacy class-based API.

Function-based API (v3.0+)#

The new API provides a simpler, more intuitive interface for time series aggregation.

Main Function#

New simplified API for tsam aggregation.

tsam.api.aggregate(data: DataFrame, n_clusters: int, *, period_duration: int | float | str = 24, temporal_resolution: float | str | None = None, cluster: ClusterConfig | None = None, segments: SegmentConfig | None = None, extremes: ExtremeConfig | None = None, preserve_column_means: bool = True, rescale_exclude_columns: list[str] | None = None, round_decimals: int | None = None, numerical_tolerance: float = 1e-13) AggregationResult[source]#

Aggregate time series data into typical periods.

This function reduces a time series dataset to a smaller set of representative “typical periods” using clustering algorithms.

Parameters#

datapd.DataFrame

Input time series data with a datetime index. Each column represents a different variable (e.g., solar, wind, demand). The index should be a DatetimeIndex with regular intervals.

n_clustersint

Number of clusters (typical periods) to create. Higher values = more accuracy but less data reduction. Typical range: 4-20 for energy system models.

period_durationint, float, or str, default 24

Length of each period. Accepts: - int/float: hours (e.g., 24 for daily, 168 for weekly) - str: pandas Timedelta string (e.g., ‘24h’, ‘1d’, ‘1w’)

temporal_resolutionfloat or str, optional

Time resolution of input data. Accepts: - float: hours (e.g., 1.0 for hourly, 0.25 for 15-minute) - str: pandas Timedelta string (e.g., ‘1h’, ‘15min’, ‘30min’) If not provided, inferred from the datetime index.

clusterClusterConfig, optional

Clustering configuration. If not provided, uses defaults: - method: “hierarchical” - representation: “medoid”

segmentsSegmentConfig, optional

Segmentation configuration for reducing temporal resolution within periods. If not provided, no segmentation is applied.

extremesExtremeConfig, optional

Configuration for preserving extreme periods. If not provided, no extreme period handling is applied.

preserve_column_meansbool, default True

Rescale typical periods so each column’s weighted mean matches the original data’s mean. Ensures total energy/load is preserved when weights represent occurrence counts.

rescale_exclude_columnslist[str], optional

Column names to exclude from rescaling when preserve_column_means=True. Useful for binary/indicator columns (0/1 values) that should not be rescaled. If None (default), all columns are rescaled.

round_decimalsint, optional

Round output values to this many decimal places. If not provided, no rounding is applied.

numerical_tolerancefloat, default 1e-13

Tolerance for numerical precision issues. Controls when warnings are raised for aggregated values exceeding the original time series bounds. Increase this value to silence warnings caused by floating-point precision errors.

Returns#

AggregationResult

Object containing: - cluster_representatives: DataFrame with aggregated periods - cluster_assignments: Which cluster each original period belongs to - cluster_weights: Occurrence count per cluster - accuracy: RMSE, MAE metrics - Methods: to_dict()

Raises#

ValueError

If input data is invalid or parameters are inconsistent.

TypeError

If parameter types are incorrect.

Examples#

Basic usage with defaults:

>>> import tsam
>>> result = tsam.aggregate(df, n_clusters=8)
>>> typical = result.cluster_representatives

With custom clustering:

>>> from tsam import aggregate, ClusterConfig
>>> result = aggregate(
...     df,
...     n_clusters=8,
...     cluster=ClusterConfig(method="kmeans", representation="mean"),
... )

With segmentation (reduce to 12 timesteps per period):

>>> from tsam import aggregate, SegmentConfig
>>> result = aggregate(
...     df,
...     n_clusters=8,
...     segments=SegmentConfig(n_segments=12),
... )

Preserving peak demand periods:

>>> from tsam import aggregate, ExtremeConfig
>>> result = aggregate(
...     df,
...     n_clusters=8,
...     extremes=ExtremeConfig(max_value=["demand"]),
... )

Transferring assignments to new data:

>>> result1 = aggregate(df_wind, n_clusters=8)
>>> result2 = result1.clustering.apply(df_all)

See Also#

ClusterConfig : Clustering algorithm configuration SegmentConfig : Temporal segmentation configuration ExtremeConfig : Extreme period preservation configuration AggregationResult : Result object with all outputs

Configuration Classes#

Configuration classes for tsam aggregation.

class tsam.config.ClusterConfig(method: Literal['averaging', 'kmeans', 'kmedoids', 'kmaxoids', 'hierarchical', 'contiguous'] = 'hierarchical', representation: Literal['mean', 'medoid', 'maxoid', 'distribution', 'distribution_minmax', 'minmax_mean'] | Distribution | MinMaxMean | None = None, weights: dict[str, float] | None = None, normalize_column_means: bool = False, use_duration_curves: bool = False, include_period_sums: bool = False, solver: Literal['highs', 'cbc', 'gurobi', 'cplex'] = 'highs')[source]#

Configuration for the clustering algorithm.

Parameters#

methodstr, default “hierarchical”

Clustering algorithm to use: - “averaging”: Sequential averaging of periods - “kmeans”: K-means clustering (fast, uses centroids) - “kmedoids”: K-medoids using MILP optimization (uses actual periods) - “kmaxoids”: K-maxoids (selects most dissimilar periods) - “hierarchical”: Agglomerative hierarchical clustering - “contiguous”: Hierarchical with temporal contiguity constraint

representationstr, Distribution, or MinMaxMean, optional

How to represent cluster centers. Accepts either a string shortcut or a typed representation object for additional options:

String shortcuts: - “mean”: Centroid (average of cluster members) - “medoid”: Actual period closest to centroid - “maxoid”: Actual period most dissimilar to others - “distribution”: Preserve value distribution (duration curve) - “distribution_minmax”: Distribution + preserve min/max values - “minmax_mean”: Combine min/max/mean per timestep

Typed objects (for additional options): - Distribution(scope="cluster"|"global", preserve_minmax=False):

Preserve value distribution. scope controls whether each cluster’s distribution is preserved separately (“cluster”) or the overall time series distribution (“global”).

  • MinMaxMean(max_columns=[...], min_columns=[...]): Combine min/max/mean per column. Columns not listed default to mean.

Default depends on method: - “mean” for averaging, kmeans - “medoid” for kmedoids, hierarchical, contiguous - “maxoid” for kmaxoids

weightsdict[str, float], optional

Per-column weights for clustering distance calculation. Higher weight = more influence on clustering. Example: {“demand”: 2.0, “solar”: 1.0}

normalize_column_meansbool, default False

Normalize all columns to the same mean before clustering. Useful when columns have very different scales.

use_duration_curvesbool, default False

Sort values within each period before clustering. Matches periods by their value distribution rather than timing.

include_period_sumsbool, default False

Include period totals as additional features for clustering. Helps preserve total energy/load values.

solverstr, default “highs”

MILP solver for kmedoids method. Options: “highs” (default, open source), “cbc”, “gurobi”, “cplex”

get_representation() Literal['mean', 'medoid', 'maxoid', 'distribution', 'distribution_minmax', 'minmax_mean'] | Distribution | MinMaxMean[source]#

Get the representation, using default if not specified.

to_dict() dict[str, Any][source]#

Convert to dictionary for JSON serialization.

classmethod from_dict(data: dict) ClusterConfig[source]#

Create from dictionary (e.g., loaded from JSON).

class tsam.config.SegmentConfig(n_segments: int, representation: Literal['mean', 'medoid', 'maxoid', 'distribution', 'distribution_minmax', 'minmax_mean'] | Distribution | MinMaxMean = 'mean')[source]#

Configuration for temporal segmentation within periods.

Segmentation reduces the temporal resolution within each typical period, grouping consecutive timesteps into segments.

Parameters#

n_segmentsint

Number of segments per period. Must be less than or equal to the number of timesteps per period. Example: period_duration=24 with hourly data has 24 timesteps, so n_segments could be 1-24.

representationstr, Distribution, or MinMaxMean, default “mean”

How to represent each segment: - “mean”: Average value of timesteps in segment - “medoid”: Actual timestep closest to segment mean - “distribution”: Preserve distribution within segment - Distribution(...): Distribution with additional options - MinMaxMean(...): Per-column min/max/mean

to_dict() dict[str, Any][source]#

Convert to dictionary for JSON serialization.

classmethod from_dict(data: dict) SegmentConfig[source]#

Create from dictionary (e.g., loaded from JSON).

class tsam.config.ExtremeConfig(method: Literal['append', 'replace', 'new_cluster']='append', max_value: list[str] = <factory>, min_value: list[str] = <factory>, max_period: list[str] = <factory>, min_period: list[str] = <factory>)[source]#

Configuration for preserving extreme periods.

Extreme periods contain critical peak values that must be preserved in the aggregated representation (e.g., peak demand for capacity sizing).

Parameters#

methodstr, default “append”

How to handle extreme periods: - “append”: Add extreme periods as additional cluster centers - “replace”: Replace the nearest cluster center with the extreme - “new_cluster”: Add as new cluster and reassign affected periods

max_valuelist[str], optional

Column names where the maximum value should be preserved. The entire period containing that single extreme value becomes an extreme period. Example: [“electricity_demand”] to preserve peak demand hour.

min_valuelist[str], optional

Column names where the minimum value should be preserved. Example: [“temperature”] to preserve coldest hour.

max_periodlist[str], optional

Column names where the period with maximum total should be preserved. Example: [“solar_generation”] to preserve highest solar day.

min_periodlist[str], optional

Column names where the period with minimum total should be preserved. Example: [“wind_generation”] to preserve lowest wind day.

has_extremes() bool[source]#

Check if any extreme periods are configured.

to_dict() dict[str, Any][source]#

Convert to dictionary for JSON serialization.

classmethod from_dict(data: dict) ExtremeConfig[source]#

Create from dictionary (e.g., loaded from JSON).

Result Classes#

Result classes for tsam aggregation.

class tsam.result.AccuracyMetrics(rmse: Series, mae: Series, rmse_duration: Series, rescale_deviations: DataFrame)[source]#

Accuracy metrics comparing aggregated to original time series.

Attributes#

rmsepd.Series

Root Mean Square Error per column.

maepd.Series

Mean Absolute Error per column.

rmse_durationpd.Series

RMSE on duration curves (sorted values) per column.

rescale_deviationspd.DataFrame

Rescaling deviation information per column. Contains columns: - deviation_pct: Final deviation percentage after rescaling - converged: Whether rescaling converged within max iterations - iterations: Number of iterations used Only populated if rescaling was enabled, otherwise empty DataFrame.

property summary: DataFrame#

Summary DataFrame with all metrics per column.

Returns#
pd.DataFrame

DataFrame with columns: rmse, mae, rmse_duration, and deviation_pct (if rescaling was enabled). Index is the original column names.

class tsam.result.AggregationResult(cluster_representatives: pd.DataFrame, cluster_weights: dict[int, int], n_timesteps_per_period: int, segment_durations: tuple[tuple[int, ...], ...] | None, accuracy: AccuracyMetrics, clustering_duration: float, clustering: ClusteringResult, is_transferred: bool, _aggregation: TimeSeriesAggregation)[source]#

Result of time series aggregation.

This class holds all outputs from the aggregation process and provides convenient methods for accessing and exporting the results.

Attributes#

cluster_representativespd.DataFrame

The aggregated typical periods with MultiIndex (cluster, timestep). Each row represents one timestep in one cluster representative.

cluster_assignmentsnp.ndarray

Which cluster each original period belongs to. Length equals the number of original periods. Values are cluster indices (0 to n_clusters-1).

cluster_weightsdict[int, int]

How many original periods each cluster represents. Keys are cluster indices, values are occurrence counts.

n_clustersint

Number of clusters (typical periods).

n_timesteps_per_periodint

Number of timesteps in each period.

n_segmentsint | None

Number of segments per period if segmentation was used, else None.

segment_durationstuple[tuple[int, …], …] | None

Duration (in timesteps) for each segment in each typical period. Outer tuple has one entry per typical period, inner tuple has duration for each segment. Use for transferring to another aggregation.

accuracyAccuracyMetrics

Accuracy metrics comparing reconstructed to original data.

clustering_durationfloat

Time taken for clustering in seconds.

is_transferredbool

Whether this result was created by applying a transferred clustering (via ClusteringResult.apply()) rather than by clustering this data directly.

Examples#

>>> result = tsam.aggregate(df, n_clusters=8)
>>> result.cluster_representatives
                    solar  wind  demand
cluster timestep
0       0           0.12   0.45   0.78
        1           0.15   0.42   0.82
...
>>> result.cluster_weights
{0: 45, 1: 52, 2: 38, ...}
>>> result.accuracy.rmse
solar     0.023
wind      0.041
demand    0.015
dtype: float64
property n_clusters: int[source]#

Number of clusters (typical periods).

Derived from the cluster_representatives DataFrame index, which is the authoritative source. Note: cluster_weights may have more entries than actual cluster IDs due to tsam quirks.

property n_segments: int | None[source]#

Number of segments per period if segmentation was used, else None.

property cluster_assignments: ndarray[source]#

Which cluster each original period belongs to.

Length equals the number of original periods. Values are cluster indices (0 to n_clusters-1).

property original: DataFrame[source]#

Original time series data.

Returns#
pd.DataFrame

The original input time series with datetime index.

Examples#
>>> result = tsam.aggregate(df, n_clusters=8)
>>> result.original.shape == df.shape
True
property reconstructed: DataFrame[source]#

Reconstructed time series from typical periods.

Each original period is replaced by its assigned cluster representative. This is cached for performance since reconstruction can be expensive.

Returns#
pd.DataFrame

Reconstructed time series with same shape as original.

Examples#
>>> result = tsam.aggregate(df, n_clusters=8)
>>> result.reconstructed.shape == df.shape
True
property residuals: DataFrame[source]#

Residuals (original - reconstructed).

Positive values indicate the original exceeded the reconstruction.

Returns#
pd.DataFrame

Residual time series with same shape as original.

Examples#
>>> result = tsam.aggregate(df, n_clusters=8)
>>> result.residuals.mean()  # Should be close to zero
to_dict() dict[source]#

Export results as a dictionary for serialization.

Returns#
dict

Dictionary containing all result data in serializable format.

property timestep_index: list[int]#

Get the timestep or segment indices.

Returns#
list[int]

List of indices [0, 1, …, n-1] where n is n_segments if segmentation was used, otherwise n_timesteps_per_period.

property period_index: list[int]#

Get the period (cluster) indices.

Returns the actual cluster IDs from the cluster_representatives DataFrame, which is the authoritative source.

Returns#
list[int]

Sorted list of cluster indices present in cluster_representatives.

property assignments: DataFrame#

Get timestep-level assignment information.

Returns a DataFrame with one row per original timestep containing assignment information for transferring results to another aggregation.

Columns#
period_idxint

Index of the original period (0-indexed, 0 to n_original_periods-1).

timestep_idxint

Timestep index within the period (0 to n_timesteps_per_period-1).

cluster_idxint

Which cluster this period is assigned to (0 to n_clusters-1).

segment_idxint (only if segmentation was used)

Which segment this timestep belongs to within its period.

Returns#
pd.DataFrame

DataFrame indexed by original time index with assignment columns.

Examples#
>>> result = tsam.aggregate(df, n_clusters=8)
>>> result.assignments.head()
                     period_idx  timestep_idx  cluster_idx
2010-01-01 00:00:00          0             0            3
2010-01-01 01:00:00          0             1            3
...
>>> # Save and reload assignments
>>> result.assignments.to_csv("assignments.csv")
property plot: ResultPlotAccessor#

Access plotting methods.

Returns a plotting accessor with methods for visualizing the results.

Returns#
ResultPlotAccessor

Accessor with plotting methods.

Examples#
>>> result = tsam.aggregate(df, n_clusters=8)
>>> result.plot.compare()  # Compare original vs reconstructed
>>> result.plot.residuals()  # View reconstruction errors
>>> result.plot.cluster_representatives()
>>> result.plot.cluster_weights()
>>> result.plot.accuracy()

Tuning Functions#

Hyperparameter tuning for tsam aggregation.

This module provides functions for finding optimal aggregation parameters.

class tsam.tuning.TuningResult(n_clusters: int, n_segments: int, rmse: float, history: list[dict], best_result: AggregationResult, all_results: list[AggregationResult] = <factory>)[source]#

Result of hyperparameter tuning.

Attributes#

n_clustersint

Optimal number of typical periods.

n_segmentsint

Optimal number of segments per period.

rmsefloat

RMSE of the optimal configuration.

historylist[dict]

History of all tested configurations with their RMSE values.

best_resultAggregationResult

The AggregationResult for the optimal configuration.

all_resultslist[AggregationResult]

All AggregationResults from tuning.

Examples#

>>> result = find_optimal_combination(df, data_reduction=0.01)
>>> result.summary  # DataFrame of all tested configs
>>> result.plot()   # Visualize results
>>> pareto = find_pareto_front(df, max_timesteps=500)
>>> pareto.find_by_timesteps(100)  # Find config closest to 100 timesteps
>>> for agg_result in pareto:      # Iterate over AggregationResults
...     print(agg_result.accuracy.rmse.mean())
property summary: DataFrame#

Summary DataFrame of all tested configurations.

find_by_timesteps(target: int) AggregationResult[source]#

Find the result closest to a target timestep count.

find_by_rmse(threshold: float) AggregationResult[source]#

Find the smallest configuration that achieves a target RMSE.

plot(show_labels: bool = True, **kwargs: object) object[source]#

Plot results (RMSE vs timesteps).

tsam.tuning.find_clusters_for_reduction(n_timesteps: int, n_segments: int, data_reduction: float) int[source]#

Calculate max clusters for a target data reduction.

Parameters#

n_timestepsint

Number of original timesteps.

n_segmentsint

Number of segments per period.

data_reductionfloat

Target reduction factor (e.g., 0.1 for 10% of original size).

Returns#

int

Maximum number of clusters that achieves the reduction.

Examples#

>>> find_clusters_for_reduction(8760, 24, 0.01)  # 1% of hourly year
3
tsam.tuning.find_segments_for_reduction(n_timesteps: int, n_clusters: int, data_reduction: float) int[source]#

Calculate max segments for a target data reduction.

Parameters#

n_timestepsint

Number of original timesteps.

n_clustersint

Number of typical periods.

data_reductionfloat

Target reduction factor (e.g., 0.1 for 10% of original size).

Returns#

int

Maximum number of segments that achieves the reduction.

Examples#

>>> find_segments_for_reduction(8760, 8, 0.01)  # 1% with 8 periods
10
tsam.tuning.find_optimal_combination(data: DataFrame, data_reduction: float, *, period_duration: int | float | str = 24, temporal_resolution: float | str | None = None, cluster: ClusterConfig | None = None, segment_representation: Literal['mean', 'medoid', 'maxoid', 'distribution', 'distribution_minmax', 'minmax_mean'] = 'mean', extremes: ExtremeConfig | None = None, preserve_column_means: bool = True, round_decimals: int | None = None, numerical_tolerance: float = 1e-13, show_progress: bool = True, save_all_results: bool = False, n_jobs: int | None = None) TuningResult[source]#

Find optimal period/segment combination for a target data reduction.

Searches the Pareto-optimal frontier of period/segment combinations that achieve the specified data reduction, returning the one with minimum RMSE.

Parameters#

datapd.DataFrame

Input time series data.

data_reductionfloat

Target reduction factor (e.g., 0.01 for 1% of original size).

period_durationint, float, or str, default 24

Length of each period. Accepts: - int/float: hours (e.g., 24 for daily, 168 for weekly) - str: pandas Timedelta string (e.g., ‘24h’, ‘1d’, ‘1w’)

temporal_resolutionfloat or str, optional

Time resolution of input data. Accepts: - float: hours (e.g., 1.0 for hourly, 0.25 for 15-minute) - str: pandas Timedelta string (e.g., ‘1h’, ‘15min’, ‘30min’) If not provided, inferred from the datetime index.

clusterClusterConfig, optional

Clustering configuration.

segment_representationstr, default “mean”

How to represent each segment: “mean” or “medoid”.

extremesExtremeConfig, optional

Configuration for preserving extreme periods.

preserve_column_meansbool, default True

Whether to rescale results to preserve original column means.

round_decimalsint, optional

Round results to this many decimal places.

numerical_tolerancefloat, default 1e-13

Numerical tolerance for floating-point comparisons.

show_progressbool, default True

Show progress bar during search.

save_all_resultsbool, default False

If True, save all AggregationResults in all_results attribute. Useful for detailed analysis but increases memory usage.

n_jobsint, optional

Number of parallel jobs. If None or 1, runs sequentially. Use -1 for all available CPUs, or a positive integer for a specific number of workers. Parallel execution uses a file-based approach where data is saved to a temp file and workers load from disk - no DataFrame pickling, safe for sensitive data.

Returns#

TuningResult

Result containing optimal parameters and history.

Examples#

>>> result = find_optimal_combination(df, data_reduction=0.01)
>>> print(f"Optimal: {result.n_clusters} periods, "
...       f"{result.n_segments} segments")
>>> # Use all CPUs for faster search (file-based, no DataFrame pickling)
>>> result = find_optimal_combination(df, data_reduction=0.01, n_jobs=-1)
tsam.tuning.find_pareto_front(data: pd.DataFrame, *, period_duration: int | float | str = 24, temporal_resolution: float | str | None = None, max_timesteps: int | None = None, timesteps: Sequence[int] | None = None, cluster: ClusterConfig | None = None, segment_representation: RepresentationMethod = 'mean', extremes: ExtremeConfig | None = None, preserve_column_means: bool = True, round_decimals: int | None = None, numerical_tolerance: float = 1e-13, show_progress: bool = True, n_jobs: int | None = None) TuningResult[source]#

Find all Pareto-optimal aggregations from 1 period to full resolution.

Uses a steepest-descent approach to efficiently explore the period/segment space, finding configurations that are optimal for their complexity level.

Parameters#

datapd.DataFrame

Input time series data.

period_durationint, float, or str, default 24

Length of each period. Accepts: - int/float: hours (e.g., 24 for daily, 168 for weekly) - str: pandas Timedelta string (e.g., ‘24h’, ‘1d’, ‘1w’)

temporal_resolutionfloat or str, optional

Time resolution of input data. Accepts: - float: hours (e.g., 1.0 for hourly, 0.25 for 15-minute) - str: pandas Timedelta string (e.g., ‘1h’, ‘15min’, ‘30min’) If not provided, inferred from the datetime index.

max_timestepsint, optional

Stop when reaching this many timesteps. If None, explores up to full resolution. Ignored if timesteps is provided.

timestepsSequence[int], optional

Specific timestep counts to explore. If provided, only evaluates configurations that produce approximately these timestep counts. Useful for faster exploration with large steps or specific ranges. Examples: range(10, 500, 10), [10, 50, 100, 200, 500]

clusterClusterConfig, optional

Clustering configuration.

segment_representationstr, default “mean”

How to represent each segment: “mean” or “medoid”.

extremesExtremeConfig, optional

Configuration for preserving extreme periods.

preserve_column_meansbool, default True

Whether to rescale results to preserve original column means.

round_decimalsint, optional

Round results to this many decimal places.

numerical_tolerancefloat, default 1e-13

Numerical tolerance for floating-point comparisons.

show_progressbool, default True

Show progress bar.

n_jobsint, optional

Number of parallel jobs for testing configurations. If None or 1, runs sequentially. Use -1 for all available CPUs. During steepest-descent phase, tests both directions in parallel.

Returns#

TuningResult

Result object containing Pareto-optimal configurations with convenience methods for analysis and visualization.

Examples#

>>> pareto = find_pareto_front(df, max_timesteps=500)
>>> pareto.summary  # DataFrame of all Pareto-optimal points
>>> pareto.plot()   # Visualize the Pareto front
>>> pareto.find_by_timesteps(100)  # Find config closest to 100 timesteps
>>> pareto.find_by_rmse(0.05)      # Find smallest config with RMSE <= 0.05
>>> # Iterate over AggregationResults
>>> for agg_result in pareto:
...     print(f"RMSE: {agg_result.accuracy.rmse.mean():.4f}")
>>> # Use parallel execution for faster search
>>> pareto = find_pareto_front(df, max_timesteps=500, n_jobs=-1)
>>> # Explore only specific timestep counts (faster)
>>> pareto = find_pareto_front(df, timesteps=range(10, 500, 50))
>>> # Explore a specific list of timestep targets
>>> pareto = find_pareto_front(df, timesteps=[10, 50, 100, 200, 500])

Legacy Class-based API#

The class-based API is still available for backward compatibility.

class tsam.timeseriesaggregation.TimeSeriesAggregation(timeSeries, resolution=None, noTypicalPeriods=10, noSegments=10, hoursPerPeriod=24, clusterMethod='hierarchical', evalSumPeriods=False, sortValues=False, sameMean=False, rescaleClusterPeriods=True, rescaleExcludeColumns=None, weightDict=None, segmentation=False, extremePeriodMethod='None', representationMethod=None, representationDict=None, distributionPeriodWise=True, segmentRepresentationMethod=None, predefClusterOrder=None, predefClusterCenterIndices=None, predefExtremeClusterIdx=None, predefSegmentOrder=None, predefSegmentDurations=None, predefSegmentCenters=None, solver='highs', numericalTolerance=1e-13, roundOutput=None, addPeakMin=None, addPeakMax=None, addMeanMin=None, addMeanMax=None)[source]#

Clusters time series data to typical periods.

__init__(timeSeries, resolution=None, noTypicalPeriods=10, noSegments=10, hoursPerPeriod=24, clusterMethod='hierarchical', evalSumPeriods=False, sortValues=False, sameMean=False, rescaleClusterPeriods=True, rescaleExcludeColumns=None, weightDict=None, segmentation=False, extremePeriodMethod='None', representationMethod=None, representationDict=None, distributionPeriodWise=True, segmentRepresentationMethod=None, predefClusterOrder=None, predefClusterCenterIndices=None, predefExtremeClusterIdx=None, predefSegmentOrder=None, predefSegmentDurations=None, predefSegmentCenters=None, solver='highs', numericalTolerance=1e-13, roundOutput=None, addPeakMin=None, addPeakMax=None, addMeanMin=None, addMeanMax=None)[source]#

Initialize the periodly clusters.

Parameters:
  • timeSeries (pandas.DataFrame() or dict) – DataFrame with the datetime as index and the relevant time series parameters as columns. required

  • resolution (float) – Resolution of the time series in hours [h]. If timeSeries is a pandas.DataFrame() the resolution is derived from the datetime index. optional, default: delta_T in timeSeries

  • hoursPerPeriod (integer) – Value which defines the length of a cluster period. optional, default: 24

  • noTypicalPeriods (integer) – Number of typical Periods - equivalent to the number of clusters. optional, default: 10

  • noSegments (integer) – Number of segments in which the typical periods shoul be subdivided - equivalent to the number of inner-period clusters. optional, default: 10

  • clusterMethod (string) –

    Chosen clustering method. optional, default: ‘hierarchical’
    Options are:

    • ’averaging’

    • ’k_means’

    • ’k_medoids’

    • ’k_maxoids’

    • ’hierarchical’

    • ’adjacent_periods’

  • evalSumPeriods (boolean) – Boolean if in the clustering process also the averaged periodly values shall be integrated additional to the periodly profiles as parameters. optional, default: False

  • sameMean (boolean) – Boolean which is used in the normalization procedure. If true, all time series get normalized such that they have the same mean value. optional, default: False

  • sortValues (boolean) – Boolean if the clustering should be done by the periodly duration curves (true) or the original shape of the data. optional (default: False)

  • rescaleClusterPeriods (boolean) – Decides if the cluster Periods shall get rescaled such that their weighted mean value fits the mean value of the original time series. optional (default: True)

  • weightDict (dict) – Dictionary which weights the profiles. It is done by scaling the time series while the normalization process. Normally all time series have a scale from 0 to 1. By scaling them, the values get different distances to each other and with this, they are differently evaluated while the clustering process. optional (default: None )

  • segmentation (boolean) – Boolean if time steps in periods should be aggregated to segments. optional (default: False)

  • extremePeriodMethod (string) –

    Method how to integrate extreme Periods (peak demand, lowest temperature etc.) into to the typical period profiles. optional, default: ‘None’
    Options are:

    • None: No integration at all.

    • ’append’: append typical Periods to cluster centers

    • ’new_cluster_center’: add the extreme period as additional cluster center. It is checked then for all Periods if they fit better to the this new center or their original cluster center.

    • ’replace_cluster_center’: replaces the cluster center of the cluster where the extreme period belongs to with the periodly profile of the extreme period. (Worst case system design)

  • representationMethod (string) –

    Chosen representation. If specified, the clusters are represented in the chosen way. Otherwise, each clusterMethod has its own commonly used default representation method.
    Options are:

    • ’meanRepresentation’ (default of ‘averaging’ and ‘k_means’)

    • ’medoidRepresentation’ (default of ‘k_medoids’, ‘hierarchical’ and ‘adjacent_periods’)

    • ’minmaxmeanRepresentation’

    • ’durationRepresentation’/ ‘distributionRepresentation’

    • ’distribtionAndMinMaxRepresentation’

  • representationDict (dict) – Dictionary which states for each attribute whether the profiles in each cluster should be represented by the minimum value or maximum value of each time step. This enables estimations to the safe side. This dictionary is needed when ‘minmaxmeanRepresentation’ is chosen. If not specified, the dictionary is set to containing ‘mean’ values only.

  • distributionPeriodWise – If durationRepresentation is chosen, you can choose whether the distribution of each cluster should be separately preserved or that of the original time series only (default: True)

  • segmentRepresentationMethod (string) –

    Chosen representation for the segments. If specified, the segments are represented in the chosen way. Otherwise, it is inherited from the representationMethod.
    Options are:

    • ’meanRepresentation’ (default of ‘averaging’ and ‘k_means’)

    • ’medoidRepresentation’ (default of ‘k_medoids’, ‘hierarchical’ and ‘adjacent_periods’)

    • ’minmaxmeanRepresentation’

    • ’durationRepresentation’/ ‘distributionRepresentation’

    • ’distribtionAndMinMaxRepresentation’

  • predefClusterOrder (list or array) – Instead of aggregating a time series, a predefined grouping is taken which is given by this list. optional (default: None)

  • predefClusterCenterIndices (list or array) – If predefClusterOrder is give, this list can define the representative cluster candidates. Otherwise the medoid is taken. optional (default: None)

  • solver (string) – Solver that is used for k_medoids clustering. optional (default: ‘cbc’ )

  • numericalTolerance (float) – Tolerance for numerical issues. Silences the warning for exceeding upper or lower bounds of the time series. optional (default: 1e-13 )

  • roundOutput (integer) – Decimals to what the output time series get round. optional (default: None )

  • addPeakMin (list) – List of column names which’s minimal value shall be added to the typical periods. E.g.: [‘Temperature’]. optional, default: []

  • addPeakMax (list) – List of column names which’s maximal value shall be added to the typical periods. E.g. [‘EDemand’, ‘HDemand’]. optional, default: []

  • addMeanMin (list) – List of column names where the period with the cumulative minimal value shall be added to the typical periods. E.g. [‘Photovoltaic’]. optional, default: []

  • addMeanMax (list) – List of column names where the period with the cumulative maximal value shall be added to the typical periods. optional, default: []

createTypicalPeriods()[source]#

Clusters the Periods.

Returns:

self.typicalPeriods – All typical Periods in scaled form.

prepareEnersysInput()[source]#

Creates all dictionaries and lists which are required for the energy system optimization input.

property stepIdx#

Index inside a single cluster

property clusterPeriodIdx#

Index of the clustered periods

property clusterOrder#

The sequence/order of the typical period to represent the original time series

property clusterPeriodNoOccur#

How often does a typical period occur in the original time series

property clusterPeriodDict#

Time series data for each period index as dictionary

property segmentDurationDict#

Segment duration in time steps for each period index as dictionary

predictOriginalData()[source]#

Predicts the overall time series if every period would be placed in the related cluster center

Returns:

predictedData (pandas.DataFrame) – DataFrame which has the same shape as the original one.

indexMatching()[source]#

Relates the index of the original time series with the indices represented by the clusters

Returns:

timeStepMatching (pandas.DataFrame) – DataFrame which has the same shape as the original one.

accuracyIndicators()[source]#

Compares the predicted data with the original time series.

Returns:

pd.DataFrame(indicatorRaw) (pandas.DataFrame) – Dataframe containing indicators evaluating the accuracy of the aggregation

totalAccuracyIndicators()[source]#

Derives the accuracy indicators over all time series

tsam.timeseriesaggregation.unstackToPeriods(timeSeries, timeStepsPerPeriod)[source]#

Extend the timeseries to an integer multiple of the period length and groups the time series to the periods.

Parameters:
  • timeSeries (pandas DataFrame)

  • timeStepsPerPeriod (integer) – The number of discrete timesteps which describe one period. required

Returns:

  • unstackedTimeSeries (pandas DataFrame) – is stacked such that each row represents a candidate period

  • timeIndex (pandas Series index) – is the modification of the original timeseriesindex in case an integer multiple was created

Deprecated since version Use: tsam.unstack_to_periods() instead.