PyPSA / PyPSA/linopy

Model.assign_coords: coordinate reassignment on an existing model

Open
#767 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

data-model enhancement performance
Dominant language
Python
Stars
257
Forks
87
Avg merge
1d 3h
Merged PRs (30d)
29

Description

[!NOTE]
The following content was generated by AI.

Describe the feature you'd like to see

A public API to reassign coordinate values on an existing model, e.g.

m.assign_coords(snapshot=new_snapshots)

which replaces the coordinate values of every variable and constraint carrying that dimension (same length, new values), mirroring xarray.Dataset.assign_coords semantics.

Context

In rolling-horizon workflows with the persistent solver interface (#718), the model structure stays identical between iterations while the window data shifts. The diff machinery already anticipates this via ignore_dims={"snapshot"}, and Variable.update() / Constraint.update() (#727) cover the data side. What is missing is moving the coordinate labels themselves, which is required so that solution/dual assignment lands on the right index after the window advances:

import linopy
import pandas as pd

sns0 = pd.date_range("2026-01-01", periods=3, freq="h", name="snapshot")
sns1 = sns0 + pd.Timedelta("1h")

m = linopy.Model()
x = m.add_variables(coords=[sns0], name="x")
m.add_constraints(x >= 0, name="c")

# desired:
# m.assign_coords(snapshot=sns1)

# today this needs private mutation per container:
for _, v in m.variables.items():
    if "snapshot" in v.dims:
        v.data["snapshot"] = sns1
for _, c in m.constraints.items():
    if "snapshot" in c.dims:
        c.data["snapshot"] = sns1
Pitfall the library should own

The obvious workaround v._data = v.data.assign_coords(snapshot=sns1) silently reorders the dataset's variables (the reassigned coord moves to the end), which broke dim inference in Model.assign_result (xr.DataArray(values, var.coords) without explicit dims). Exactly this kind of footgun is why coordinate reassignment should be a library-owned, order-safe operation rather than user code.

Scope
  • validate new values: same length per dimension, index-like
  • apply across all variables and constraints carrying the dimension (CSR-backed constraints included)
  • preserve dataset variable order
  • no relabeling, no reindexing, no shape change — values only

Benchmarked in a PyPSA-Eur rolling-horizon prototype (in-place window advance + persistent HiGHS): 1.76x end-to-end speedup on warm iterations with bitwise-identical objectives vs full rebuild.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the proposed Model.assign_coords entry point and trace how Variable.update(), Constraint.update(), and CSR-backed constraints store coordinate data. Check Model.assign_result for the ordering-sensitive behavior described in the issue. Done means validated same-length index-like values are applied to all relevant variables and constraints without relabeling, reindexing, shape changes, or dataset variable reordering.

Written by the indexing model from the issue text.

Assessment

Tech stack
pandas, python
Domain
backend-api-design
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.