microsoft/qlib · error · ValueError

The indexes of self and other do not meet the requirements o

Error message

The indexes of self and other do not meet the requirements of the four arithmetic operations

What it means

Before arithmetic on two SingleData objects, qlib aligns their indexes: identical (or same-set, different-order) indexes are fine — the latter triggers an implicit other.reindex(self.index) — but if the index SETS differ at all, alignment is impossible and ValueError is raised. It is qlib's strict version of pandas' automatic union alignment.

Source

Thrown at qlib/utils/index_data.py:565

            if len(data) > 0:
                index, data = zip(*data.items())
            else:
                index, data = [], []
        elif isinstance(data, pd.Series):
            assert len(index) == 0
            index, data = data.index, data.values
        elif isinstance(data, (int, float, np.number)):
            data = [data]
        super().__init__(data, index)
        assert self.ndim == 1

    def _align_indices(self, other):
        if self.index == other.index:
            return other
        elif set(self.index) == set(other.index):
            return other.reindex(self.index)
        else:
            raise ValueError(
                f"The indexes of self and other do not meet the requirements of the four arithmetic operations"
            )

    def reindex(self, index: Index, fill_value=np.nan) -> SingleData:
        """reindex data and fill the missing value with np.nan.

        Parameters
        ----------
        new_index : list
            new index
        fill_value:
            what value to fill if index is missing

        Returns
        -------
        SingleData
            reindex data
        """

View on GitHub (pinned to 79633dd950)

Solutions

  1. Explicitly align first: b = b.reindex(a.index) (missing entries become NaN), then a + b.
  2. Intersect the indexes before operating: common = a.index & b.index; a = a.fetch(common); b = b.fetch(common).
  3. When one operand is a scalar, pass the plain number (int/float) instead of wrapping it in a SingleData with an unrelated index.

Example fix

// before
c = a + b  # ValueError: different index sets

// after
b = b.reindex(a.index)  # fills missing dates with NaN
c = a + b
Defensive patterns

Strategy: validation

Validate before calling

if set(a.index.idx_list) != set(b.index.idx_list):
    b = b.reindex(a.index)  # explicit align, NaN-filled
c = a + b

Type guard

def indexes_compatible(a, b) -> bool:
    return a.index == b.index or set(a.index.idx_list) == set(b.index.idx_list)

Try / catch

try:
    c = a + b
except ValueError:
    b = b.reindex(a.index)
    c = a + b

Prevention

When it happens

Trigger: a + b where SingleData a and b have any non-shared index element, e.g. a covers dates 2020-01-01..2020-01-10 and b covers 2020-01-05..2020-01-15; also arithmetic against another SingleData built from a different instrument/calendar.

Common situations: Arithmetic between series fetched from different data handlers, calendars (QLIB vs custom exchange) or instruments; operations on data spanning different date ranges after filtering; forgetting that qlib (unlike pandas) does not align on index union with NaN fill.

Related errors


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