microsoft/qlib · error · ValueError

Empty data from dataset, please check your dataset config.

Error message

Empty data from dataset, please check your dataset config.

What it means

Raised at the start of TransformerModel.fit after preparing train/valid/test DataFrames with data_key=DK_L. If the train or valid frame has zero rows, fitting cannot proceed, so the model refuses with this ValueError before building the network/optimizer.

Source

Thrown at qlib/contrib/model/pytorch_transformer.py:169

                score = self.metric_fn(pred, label)
                scores.append(score.item())

        return np.mean(losses), np.mean(scores)

    def fit(
        self,
        dataset: DatasetH,
        evals_result=dict(),
        save_path=None,
    ):
        df_train, df_valid, df_test = dataset.prepare(
            ["train", "valid", "test"],
            col_set=["feature", "label"],
            data_key=DataHandlerLP.DK_L,
        )
        if df_train.empty or df_valid.empty:
            raise ValueError("Empty data from dataset, please check your dataset config.")

        x_train, y_train = df_train["feature"], df_train["label"]
        x_valid, y_valid = df_valid["feature"], df_valid["label"]

        save_path = get_or_create_path(save_path)
        stop_steps = 0
        train_loss = 0
        best_score = -np.inf
        best_epoch = 0
        evals_result["train"] = []
        evals_result["valid"] = []

        # train
        self.logger.info("training...")
        self.fitted = True

        for step in range(self.n_epochs):
            self.logger.info("Epoch%d:", step)

View on GitHub (pinned to 79633dd950)

Solutions

  1. Print dataset.prepare('train', col_set=['feature','label']).shape and the same for 'valid' — both must be non-empty.
  2. Move segment start/end dates inside the range actually covered by the handler's data (check df_calendar or the underlying handler's first/last timestamps).
  3. Adjust label processors (e.g. shorter Ref horizon) or widen the segment so rows survive dropna.
  4. Confirm the data handler was initialized with data that exists locally / via the provider before fit.

Example fix

# before
segments = {"train": ("2000-01-01", "2004-12-31"), "valid": ("2005-01-01", "2006-12-31")}  # before data starts

# after
segments = {"train": ("2008-01-01", "2014-12-31"), "valid": ("2015-01-01", "2016-12-31")}
assert len(dataset.prepare("train", col_set=["feature", "label"])) > 0
Defensive patterns

Strategy: validation

Validate before calling

for seg in ("train", "valid"):
    df = dataset.prepare(seg, col_set=["feature", "label"], data_key="learn")
    assert not df.empty, f"{seg} segment empty — check segment dates vs data calendar and dropna processors"

Try / catch

try:
    model.fit(dataset, evals_result)
except ValueError as e:
    if "Empty data" in str(e):
        raise RuntimeError("Fix DatasetH segment config / data coverage before fitting") from e
    raise

Prevention

When it happens

Trigger: fit(dataset) where dataset.prepare('train') or dataset.prepare('valid') (col_set=['feature','label']) returns an empty DataFrame — segment dates outside the data calendar, wrong segment names, or processors eliminating all rows.

Common situations: Requesting a train window before the stock data begins (common when switching markets, e.g. CSI300 vs a custom universe with later coverage); DropnaLabel removing all rows because the label horizon extends past available data; mistyped segment keys in the DatasetH segments dict.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/be4ed4df4e40cf74. Report an issue: GitHub.