diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 0a42d6b4..51063d13 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -6,6 +6,7 @@ Upcoming Version * The internal handling of `Solution` objects was improved for more consistency. Solution objects created from solver calls now preserve the exact index names from the input file. * Multiplication of a linear expression by a constant value may now introduce new dimensions. +* Added method `unstack` to `LinearExpression`, `Variable` and `Constraint` to unstack a dimension. Version 0.4.4 -------------- diff --git a/linopy/constraints.py b/linopy/constraints.py index 0fa2744f..c7a0816a 100644 --- a/linopy/constraints.py +++ b/linopy/constraints.py @@ -675,6 +675,8 @@ def to_polars(self): stack = conwrap(Dataset.stack) + unstack = conwrap(Dataset.unstack) + iterate_slices = iterate_slices diff --git a/linopy/expressions.py b/linopy/expressions.py index cf6443be..a3bb8a75 100644 --- a/linopy/expressions.py +++ b/linopy/expressions.py @@ -1472,6 +1472,8 @@ def to_polars(self) -> pl.DataFrame: stack = exprwrap(Dataset.stack) + unstack = exprwrap(Dataset.unstack) + iterate_slices = iterate_slices diff --git a/linopy/variables.py b/linopy/variables.py index 6ea667e6..108a290f 100644 --- a/linopy/variables.py +++ b/linopy/variables.py @@ -1095,6 +1095,8 @@ def equals(self, other: Variable) -> bool: stack = varwrap(Dataset.stack) + unstack = varwrap(Dataset.unstack) + iterate_slices = iterate_slices diff --git a/test/test_constraint.py b/test/test_constraint.py index 0d0080fa..a5db519d 100644 --- a/test/test_constraint.py +++ b/test/test_constraint.py @@ -197,7 +197,7 @@ def test_constraint_wrapped_methods(x, y): con.rename({"first": "new_labels"}) con.rename_dims({"first": "new_labels"}) con.roll({"first": 1}) - con.stack(new_dim=("first", "second")) + con.stack(new_dim=("first", "second")).unstack("new_dim") def test_anonymous_constraint_sel(x, y): diff --git a/test/test_linear_expression.py b/test/test_linear_expression.py index 017d165f..452ce9b2 100644 --- a/test/test_linear_expression.py +++ b/test/test_linear_expression.py @@ -669,6 +669,13 @@ def test_variable_stack(v): assert result.coord_dims == ("new",) +def test_linear_expression_unstack(v): + result = v.to_linexpr().expand_dims("new_dim").stack(new=("new_dim", "dim_2")) + result = result.unstack("new") + assert isinstance(result, LinearExpression) + assert result.coord_dims == ("new_dim", "dim_2") + + def test_linear_expression_diff(v): diff = v.to_linexpr().diff("dim_2") assert diff.nterm == 2 diff --git a/test/test_variable.py b/test/test_variable.py index 321bc3d5..57315219 100644 --- a/test/test_variable.py +++ b/test/test_variable.py @@ -267,6 +267,12 @@ def test_variable_stack(x): assert result.dims == ("new",) +def test_variable_unstack(x): + result = x.expand_dims("new_dim").stack(new=("new_dim", "first")).unstack("new") + assert isinstance(result, linopy.variables.Variable) + assert result.dims == ("new_dim", "first") + + def test_variable_flat(x): result = x.flat assert isinstance(result, pd.DataFrame)