flixopt.clustering.base ¶
Clustering classes for time series aggregation.
This module provides the Clustering class stored on FlowSystem after clustering, wrapping tsam_xarray's ClusteringResult for structure access and AggregationResult for full data access (pre-serialization only).
Classes¶
Clustering ¶
Clustering(clustering_result: ClusteringResult | dict | None = None, original_timesteps: DatetimeIndex | list[str] | None = None, _aggregation_result: AggregationResult | None = None, _unrename_map: dict[str, str] | None = None)
Clustering information for a FlowSystem.
Wraps tsam_xarray's ClusteringResult for structure access and optionally AggregationResult for full data access (pre-serialization only).
For advanced access to clustering structure (dims, coords, cluster_centers, segment_centers, etc.), use clustering_result directly.
Example
clustering = fs_clustered.clustering clustering.n_clusters 8 clustering.clustering_result # tsam_xarray ClusteringResult for full access
Attributes¶
clustering_result property ¶
tsam_xarray ClusteringResult for reuse with apply_clustering().
n_original_clusters property ¶
Number of original periods (before clustering).
n_segments property ¶
Number of segments per cluster, or None if not segmented.
cluster_assignments property ¶
Mapping from original periods to cluster IDs.
Returns:
| Type | Description |
|---|---|
DataArray | DataArray with dims [original_cluster, period?, scenario?]. |
cluster_occurrences property ¶
How many original clusters map to each typical cluster.
Returns:
| Type | Description |
|---|---|
DataArray | DataArray with dims [cluster, period?, scenario?]. |
segment_assignments property ¶
For each timestep within a cluster, which segment it belongs to.
Returns:
| Type | Description |
|---|---|
DataArray | None | DataArray with dims [cluster, time, period?, scenario?], or None if not segmented. |
segment_durations property ¶
Duration of each segment in timesteps.
Returns:
| Type | Description |
|---|---|
DataArray | None | DataArray with dims [cluster, segment, period?, scenario?], or None if not segmented. |
aggregation_result property ¶
The tsam_xarray AggregationResult for full data access.
Only available before serialization. After loading from file, use clustering_result for structure-only access.
The returned object holds the raw tsam_xarray result, on which flixopt's reserved-dim renames are still applied (the period dim is _period). For a friendlier view with the original dim names, use the original / reconstructed / residuals / accuracy properties or compare() instead.
Raises:
| Type | Description |
|---|---|
ValueError | If accessed on a Clustering loaded from JSON/NetCDF. |
original property ¶
Original (input) time series fed to clustering, on the original time axis.
All time-varying inputs are stacked on a variable dim. Dims are (*dim_names, variable, time) — e.g. (period, scenario, variable, time).
Only available before serialization.
reconstructed property ¶
Clustered profiles mapped back onto the original time axis.
Same dims and shape as original (dim order aligned with it), so the two can be compared, subtracted, or plotted directly.
Only available before serialization.
residuals property ¶
original - reconstructed, the per-timestep aggregation error.
Only available before serialization.
accuracy property ¶
tsam_xarray AccuracyMetrics (per-variable and column-weighted).
Exposes rmse / mae / rmse_duration (dims (variable, *dim_names)) and the aggregate weighted_rmse / weighted_mae / weighted_rmse_duration (dims (*dim_names,)). Dim names are un-renamed to match original.
Only available before serialization.
Methods:¶
disaggregate ¶
Expand clustered data back to original timesteps.
Delegates to tsam_xarray's ClusteringResult.disaggregate(). Handles the dim rename from flixopt's (cluster, time) to tsam_xarray's (cluster, timestep) convention.
For non-segmented systems, values are repeated for each timestep in the period. For segmented systems, values are placed at segment boundaries with NaN elsewhere — use .ffill(), .interpolate_na(), or .fillna() on the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data | DataArray | DataArray with | required |
Returns:
| Type | Description |
|---|---|
DataArray | DataArray with |
apply ¶
Apply the saved clustering to new data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data | DataArray | DataArray with time series data to cluster. | required |
Returns:
| Type | Description |
|---|---|
AggregationResult | tsam_xarray AggregationResult with the clustering applied. |
to_json ¶
from_json classmethod ¶
Load a clustering from JSON.
The loaded Clustering has full apply() and disaggregate() support because ClusteringResult is fully preserved via serialization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path | str | Path | Path to the JSON file. | required |
original_timesteps | DatetimeIndex | None | Original timesteps for the new FlowSystem. If None, uses the timesteps stored in the JSON. | None |
Returns:
| Type | Description |
|---|---|
Clustering | A Clustering that can be used with apply_clustering(). |
compare ¶
Tidy original-vs-clustered comparison, ready for plotting.
Returns a Dataset with data_vars original and clustered on the original time axis and matching dim order, so .to_dataframe() and plotting libraries need no reshaping. This is the v7 replacement for the removed clustering.plot.compare().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variable | str | list[str] | None | Optional column name (or list) to select from the | None |
Returns:
| Type | Description |
|---|---|
Dataset | xr.Dataset with variables |
Examples:
>>> import plotly.express as px
>>> cmp = clustering.compare('HeatDemand(Q)|fixed_relative_profile')
>>> px.line(cmp.to_dataframe()[['original', 'clustered']]).show()
Only available before serialization.