Repository navigation
feat: long-form inputs via from_long and relation group-by via Relation (#1019 step 5) - #1059
Draft
FabianHofmann wants to merge 3 commits into
Draft
FabianHofmann wants to merge 3 commits into
FabianHofmann wants to merge 3 commits into
Conversation
Table pivots pandas/polars long tables onto target coords for bounds, coefficients, constants, rhs and penalty. expr.groupby(relation_frame).sum() scatters repeated member rows through from_grouper on both stores; quadratic relation group-by raises.
Merging this PR will not alter performance
Comparing Footnotes
|
…n replace lazy Table Long tables convert to a DataArray at the call site with strict key checks; nothing leaks into ConstantLike or alignment. groupby takes linopy.Relation instead of detecting relation frames by shape.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1049. Part of #1019 (step 5, the last step).
Note
The following content was generated by AI.
Changes proposed in this Pull Request
linopy.from_long(frame, value, coords, default=np.nan) -> DataArray. Converts a long table (polars or pandas frame: key columns named after dims plus one named value column) to a DataArray over the key dims, eagerly at the call site. Cells not listed takedefault; dims ofcoordswithout a key column are left to linopy's usual broadcasting. The result is an ordinary DataArray, so it works everywhere a constant does (bounds, coefficients, arithmetic, rhs, penalty) and passes the strict 1.0 alignment unchanged; nothing is added toConstantLikeoras_dataarray.Strict schema, fail fast: missing value column, no key column, key not a dim, null keys, non-numeric or null values, duplicate keys, keys outside the coords, a key dtype family (numeric / temporal / string) or time zone differing from the coord, lossy key casts, and pandas frames with a non-default index raise.
pl.LazyFrame, Series and MultiIndex forms are not accepted.Pivot: polars keys are mapped to positions by a left join against each coord (arithmetic for a
RangeIndex), combined into a flat index in polars, checked for duplicates withn_unique, then scattered into onenp.fullbuffer; a full, sorted table is reshaped without the buffer. pandas input usesIndex.get_indexer(no pyarrow dependency).linopy.Relation(frame, member, group)for relation group-by.expr.groupby(Relation(...)).sum()sums over a mapping with repeated member keys, e.g. link port → bus. Member rows are gathered (Store.take_positions, now public) and scattered through the unchangedfrom_grouper, so both stores share one path; members listed in no row drop out. A bare frame passed togroupbyraises and points toRelation. Quadratic expressions raiseNotImplementedError.Benchmark: long table → 10k × 2920 cube
Table(first draft)from_long, polarsfrom_long, pandasReview and tests
A first draft used a lazy
linopy.Tableconstant pivoted once target coords were known; it leaked into ~40ConstantLikecall sites and converted polars through Python lists and a cube-sized MultiIndex. A design pass replaced it with the eager function above and made relations explicit.Branch review (four reviewers plus a coordinator) on the first draft found one must-fix (quadratic relation group-by crashed), fixed. Not addressed: sparse quadratic group-by with a plain Series already fails on master; a cube too large for
np.prodgives an unclearIndexError.Full suite: 4978 passed, 84 skipped.
mypy .,ruff check .,ruff format --check .and the doctests pass.Checklist
AGENTS.md).doc.doc/release_notes.rstof the upcoming release is included.