Source code for marivo.analysis.frames.delta
"""DeltaFrame and DeltaFrameMeta."""
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Literal
from pydantic import ConfigDict, Field
from marivo.analysis.frames.base import BaseFrame, BaseFrameMeta, assert_semantic_shape
if TYPE_CHECKING:
from marivo.analysis.frames.component import ComponentFrame
from marivo.analysis.intents._shape import AttributionShape
class DeltaFrameMeta(BaseFrameMeta):
model_config = ConfigDict(extra="forbid")
kind: Literal["delta_frame"] = "delta_frame"
metric_id: str
unit: str | None = None
source_current_ref: str
source_baseline_ref: str
alignment: dict[str, Any]
semantic_kind: Literal["scalar", "time_series", "segmented", "panel"]
semantic_model: str
normalization: dict[str, Any] | None = None
component_ref: str | None = None
composition: dict[str, Any] | None = None
fold: dict[str, Any] | None = None
component_folds: list[dict[str, Any]] = Field(default_factory=list)
[docs]
@dataclass(repr=False)
class DeltaFrame(BaseFrame):
meta: DeltaFrameMeta
_NEXT_INTENTS = ("decompose", "discover", "transform")
def _repr_identity(self) -> str:
unit_part = f" unit={self.meta.unit}" if self.meta.unit else ""
return (
f"DeltaFrame ref={self.meta.ref} metric={self.meta.metric_id}"
f"{unit_part} rows={self.meta.row_count}"
)
@property
def semantic_shape(self) -> Literal["scalar", "time_series", "segmented", "panel"]:
"""The frame's semantic shape (distinct from .shape, the dataframe dims)."""
return self.meta.semantic_kind
def as_scalar(self) -> DeltaFrame:
assert_semantic_shape(
got=self.meta.semantic_kind, expected="scalar", frame_kind=self.meta.kind
)
return self
def as_time_series(self) -> DeltaFrame:
assert_semantic_shape(
got=self.meta.semantic_kind, expected="time_series", frame_kind=self.meta.kind
)
return self
def as_segmented(self) -> DeltaFrame:
assert_semantic_shape(
got=self.meta.semantic_kind, expected="segmented", frame_kind=self.meta.kind
)
return self
def as_panel(self) -> DeltaFrame:
assert_semantic_shape(
got=self.meta.semantic_kind, expected="panel", frame_kind=self.meta.kind
)
return self
[docs]
def predicted_attribution_shape(self) -> AttributionShape:
"""Predict the AttributionFrame shape decompose will produce for this delta.
Reads this delta's component_ref + decomposition kind only (no component
load); "sum" when not component-aware, else "ratio_mix"/"weighted_mix".
"""
from marivo.analysis.intents._shape import attribution_output_shape
return attribution_output_shape(self.meta)
[docs]
def components(self) -> ComponentFrame:
"""Load the linked ComponentFrame for component-aware deltas."""
from marivo.analysis.frames._component import _load_component_frame
return _load_component_frame(
parent_ref=self.ref,
parent_kind=self.meta.kind,
session_id=self.meta.session_id,
project_root=self.meta.project_root,
artifact_id=self.meta.artifact_id,
component_ref=self.meta.component_ref,
composition=self.meta.composition,
advice="re-run compare() to regenerate it",
)