HKUDS/Vibe-Trading · error · ValueError

groups array cannot be empty

Error message

groups array cannot be empty

What it means

group_purged_kfold_splits needs a groups array assigning each observation to a group (e.g. ticker, day, session); an empty array gives no basis for splitting and is rejected before any fold construction.

Source

Thrown at agent/src/quantlib/crossvalidation.py:311

        n_folds: Number of folds, at least :data:`MIN_FOLDS`.
        embargo_fraction: Fraction of unique ordered groups embargoed after each test block.

    Yields:
        One :class:`Split` per fold, with ``train`` and ``test`` containing row indices.

    Raises:
        ValueError: If ``n_folds`` is invalid, fewer unique groups than folds exist,
            or ``embargo_fraction`` is out of bounds.
    """
    if n_folds < MIN_FOLDS:
        raise ValueError(f"n_folds must be at least {MIN_FOLDS}, got {n_folds}")
    if not 0.0 <= embargo_fraction < 1.0:
        raise ValueError(f"embargo_fraction must be in [0, 1), got {embargo_fraction}")

    grp_array = np.asarray(groups)
    n_samples = len(grp_array)
    if n_samples == 0:
        raise ValueError("groups array cannot be empty")

    # Find unique groups preserving chronological order of appearance
    unique_groups, first_indices = np.unique(grp_array, return_index=True)
    # Sort by appearance order
    order = np.argsort(first_indices)
    unique_groups = unique_groups[order]
    n_groups = len(unique_groups)

    if n_groups < n_folds:
        raise ValueError(f"{n_groups} unique groups cannot make {n_folds} folds")

    # Map each group to its member row indices
    group_to_rows: dict[object, np.ndarray] = {}
    for idx, g in enumerate(grp_array):
        group_to_rows.setdefault(g, []).append(idx)
    for g in group_to_rows:
        group_to_rows[g] = np.array(group_to_rows[g], dtype=int)

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Check the sample is non-empty before splitting; fix upstream filtering that emptied it
  2. Verify the groups column name exists and aligns with X's rows
  3. Fall back to purged_kfold_splits with label_end_times when no grouping applies

Example fix

// before
splits = list(group_purged_kfold_splits(X_empty, groups=g_empty, n_folds=5))
// after
if len(X) == 0:
    raise ValueError('no data for this period')
splits = list(group_purged_kfold_splits(X, groups=df['ticker'], n_folds=5))
Defensive patterns

Strategy: validation

Validate before calling

groups = np.asarray(groups)
assert groups.size > 0, 'groups array is empty'
assert len(groups) == len(X)

Prevention

When it happens

Trigger: Calling group_purged_kfold_splits(X, groups=np.array([])) or with an empty list, e.g. because the grouping column was dropped or the frame was pre-filtered to zero rows.

Common situations: Empty dataframe after date filtering or NaN drops, groups column selected by a wrong name yielding an empty Series, or running a backtest loop over a period with no data.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/f672bced5cb02b2a. Report an issue: GitHub.