Skip to content

check_panel_groups_match

yohou.utils.validation.check_panel_groups_match(y, X_actual)

Validate that y and X_actual have compatible panel group structures.

When both DataFrames contain panel columns (using the __ separator), they must share the same entity prefixes. For example, if y has "store_1__sales" and "store_2__sales", then X_actual must also have panel columns with "store_1__" and "store_2__" prefixes.

Global-only X_actual (no __ columns) is always valid regardless of y's structure. Global features are broadcast to every panel group.

Parameters

Name Type Description Default
y DataFrame or None

Target DataFrame. Can be None.

required
X_actual DataFrame or None

Feature DataFrame. Can be None.

required

Raises

Type Description
ValueError

If both y and X_actual have panel columns but with different group prefixes, or if y is global but X_actual has panel columns.

Examples

>>> import polars as pl
>>> from datetime import datetime
>>> # Valid: both have same entity prefixes
>>> y = pl.DataFrame({
...     "time": [datetime(2020, 1, 1)],
...     "store_1__sales": [10],
...     "store_2__sales": [20],
... })
>>> X_actual = pl.DataFrame({
...     "time": [datetime(2020, 1, 1)],
...     "store_1__temp": [100],
...     "store_2__temp": [200],
... })
>>> check_panel_groups_match(y, X_actual)  # No error
>>> # Valid: panel y with global-only X_actual (broadcast to all groups)
>>> X_global = pl.DataFrame({
...     "time": [datetime(2020, 1, 1)],
...     "weather": [25.0],
... })
>>> check_panel_groups_match(y, X_global)  # No error
>>> # Invalid: different entity prefixes
>>> X_bad = pl.DataFrame({
...     "time": [datetime(2020, 1, 1)],
...     "sensor_1__temp": [25.0],
... })
>>> check_panel_groups_match(y, X_bad)
Traceback (most recent call last):
    ...
ValueError: Panel groups mismatch between y and X_actual...

See Also

Source Code

Show/Hide source
def check_panel_groups_match(
    y: pl.DataFrame | None,
    X_actual: pl.DataFrame | None,
) -> None:
    """Validate that y and X_actual have compatible panel group structures.

    When both DataFrames contain panel columns (using the ``__`` separator),
    they must share the same entity prefixes. For example, if y has
    ``"store_1__sales"`` and ``"store_2__sales"``, then X_actual must also have
    panel columns with ``"store_1__"`` and ``"store_2__"`` prefixes.

    Global-only X_actual (no ``__`` columns) is always valid regardless of y's
    structure. Global features are broadcast to every panel group.

    Parameters
    ----------
    y : pl.DataFrame or None
        Target DataFrame. Can be None.
    X_actual : pl.DataFrame or None
        Feature DataFrame. Can be None.

    Raises
    ------
    ValueError
        If both y and X_actual have panel columns but with different group prefixes,
        or if y is global but X_actual has panel columns.

    Examples
    --------
    >>> import polars as pl
    >>> from datetime import datetime
    >>> # Valid: both have same entity prefixes
    >>> y = pl.DataFrame({
    ...     "time": [datetime(2020, 1, 1)],
    ...     "store_1__sales": [10],
    ...     "store_2__sales": [20],
    ... })
    >>> X_actual = pl.DataFrame({
    ...     "time": [datetime(2020, 1, 1)],
    ...     "store_1__temp": [100],
    ...     "store_2__temp": [200],
    ... })
    >>> check_panel_groups_match(y, X_actual)  # No error

    >>> # Valid: panel y with global-only X_actual (broadcast to all groups)
    >>> X_global = pl.DataFrame({
    ...     "time": [datetime(2020, 1, 1)],
    ...     "weather": [25.0],
    ... })
    >>> check_panel_groups_match(y, X_global)  # No error

    >>> # Invalid: different entity prefixes
    >>> X_bad = pl.DataFrame({
    ...     "time": [datetime(2020, 1, 1)],
    ...     "sensor_1__temp": [25.0],
    ... })
    >>> check_panel_groups_match(y, X_bad)  # doctest: +SKIP
    Traceback (most recent call last):
        ...
    ValueError: Panel groups mismatch between y and X_actual...

    See Also
    --------
    - [`check_panel_internal_consistency`][yohou.utils.validation.check_panel_internal_consistency] : Validate panel groups have consistent structure.
    - [`check_groups`][yohou.utils.validation.check_groups] : Validate panel group names for forecaster operations.
    - [`inspect_panel`][yohou.utils.panel.inspect_panel] : Detect panel groups in a DataFrame.

    """
    if y is None or X_actual is None:
        return  # Can't check if one is missing

    _, y_groups = inspect_panel(y)
    _, X_groups = inspect_panel(X_actual)

    # Global-only X_actual (no panel columns) is valid with any y structure.
    # Global features are broadcast to every panel group.
    if X_groups and set(y_groups.keys()) != set(X_groups.keys()):
        raise ValueError(
            f"Panel groups mismatch between `y` and `X_actual`. "
            f"`y` groups: {sorted(y_groups.keys())}, "
            f"`X_actual` groups: {sorted(X_groups.keys())}."
        )