microsoft/qlib · error · ValueError

Not supported

Error message

Not supported

What it means

IndexData.__getitem__ applies numpy-style indexing to the data matrix and its indices, then decides the wrapper class from the resulting data's ndim: 1-D becomes SingleData, 2-D becomes MultiData. If fancy/combination indexing leaves a 3-D or higher array, there is no container for it and qlib raises ValueError('Not supported').

Source

Thrown at qlib/utils/index_data.py:312

        # 2) select data and index
        new_data = self._bind_id.data[tuple(int_indexing)]
        # return directly if it is scalar
        if new_data.ndim == 0:
            return new_data
        # otherwise we go on to the index part
        new_indices = [idx[indexing] for idx, indexing in zip(self._indices, int_indexing)]

        # 3) squash dimensions
        new_indices = [
            idx for idx in new_indices if isinstance(idx, np.ndarray) and idx.ndim > 0
        ]  # squash the zero dim indexing

        if new_data.ndim == 1:
            cls = SingleData
        elif new_data.ndim == 2:
            cls = MultiData
        else:
            raise ValueError("Not supported")
        return cls(new_data, *new_indices)


class BinaryOps:
    def __init__(self, method_name):
        self.method_name = method_name

    def __get__(self, obj, *args):
        # bind object
        self.obj = obj
        return self

    def __call__(self, other):
        self_data_method = getattr(self.obj.data, self.method_name)

        if isinstance(other, (int, float, np.number)):
            return self.obj.__class__(self_data_method(other), *self.obj.indices)
        elif isinstance(other, self.obj.__class__):

View on GitHub (pinned to 79633dd950)

Solutions

  1. Flatten your indexers: pass 1-D index arrays (e.g. np.array([0,1]) and np.array([2,3])) so the result stays 2-D or 1-D.
  2. Split the operation into multiple simple slices and concat the results with concat(..., axis=0 or 1).
  3. Drop down to numpy directly (obj.data[np.ix_(rows, cols)]) when you truly need higher-dimensional fancy indexing, and manage indices yourself.

Example fix

// before
sel = mdata[[0, 1], [[0], [2]]]  # ndim=3 -> ValueError

// after
sel = mdata[np.array([0, 1]), np.array([0, 2])]  # 1-D indexers -> 2-D result
Defensive patterns

Strategy: validation

Validate before calling

rows = np.asarray(rows).ravel()
cols = np.asarray(cols).ravel()
sel = mdata[rows, cols]  # 1-D indexers keep result ndim <= 2

Type guard

def are_flat_indexers(*idxers) -> bool:
    return all(np.asarray(i).ndim <= 1 for i in idxers)

Prevention

When it happens

Trigger: Slicing a MultiData with index arrays whose combination produces ndim>2, e.g. multi_data[np.array([0,1]), np.array([[0],[1]])], or passing nested lists of indexers where each inner list adds a dimension.

Common situations: Translating advanced pandas .loc indexing (nested lists like df.loc[[['a','b']]]) into qlib IndexData; batched lookups built programmatically that accidentally nest one list too deep; refactoring data-handler code that assumed arbitrary numpy indexing support.

Related errors


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