{"record":{"id":"1c0675af5122c6be","repo":"microsoft/qlib","slug":"not-supported","errorCode":null,"errorMessage":"Not supported","messagePattern":"Not supported","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/utils/index_data.py","lineNumber":312,"sourceCode":"        # 2) select data and index\n        new_data = self._bind_id.data[tuple(int_indexing)]\n        # return directly if it is scalar\n        if new_data.ndim == 0:\n            return new_data\n        # otherwise we go on to the index part\n        new_indices = [idx[indexing] for idx, indexing in zip(self._indices, int_indexing)]\n\n        # 3) squash dimensions\n        new_indices = [\n            idx for idx in new_indices if isinstance(idx, np.ndarray) and idx.ndim > 0\n        ]  # squash the zero dim indexing\n\n        if new_data.ndim == 1:\n            cls = SingleData\n        elif new_data.ndim == 2:\n            cls = MultiData\n        else:\n            raise ValueError(\"Not supported\")\n        return cls(new_data, *new_indices)\n\n\nclass BinaryOps:\n    def __init__(self, method_name):\n        self.method_name = method_name\n\n    def __get__(self, obj, *args):\n        # bind object\n        self.obj = obj\n        return self\n\n    def __call__(self, other):\n        self_data_method = getattr(self.obj.data, self.method_name)\n\n        if isinstance(other, (int, float, np.number)):\n            return self.obj.__class__(self_data_method(other), *self.obj.indices)\n        elif isinstance(other, self.obj.__class__):","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/utils/index_data.py#L294-L330","documentation":"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').","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Split the operation into multiple simple slices and concat the results with concat(..., axis=0 or 1).","Drop down to numpy directly (obj.data[np.ix_(rows, cols)]) when you truly need higher-dimensional fancy indexing, and manage indices yourself."],"exampleFix":"// before\nsel = mdata[[0, 1], [[0], [2]]]  # ndim=3 -> ValueError\n\n// after\nsel = mdata[np.array([0, 1]), np.array([0, 2])]  # 1-D indexers -> 2-D result","handlingStrategy":"validation","validationCode":"rows = np.asarray(rows).ravel()\ncols = np.asarray(cols).ravel()\nsel = mdata[rows, cols]  # 1-D indexers keep result ndim <= 2","typeGuard":"def are_flat_indexers(*idxers) -> bool:\n    return all(np.asarray(i).ndim <= 1 for i in idxers)","tryCatchPattern":null,"preventionTips":["Always pass 1-D index arrays to IndexData.__getitem__; np.ix_ also guarantees outer-product 2-D behavior.","Never translate pandas nested-list indexing (df.loc[[['a','b']]]) directly to qlib containers."],"tags":["qlib","index-data","numpy-indexing","valueerror","slicing"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}