{"record":{"id":"4126537025353043","repo":"microsoft/qlib","slug":"please-implement-the-droplevel-method","errorCode":null,"errorMessage":"Please implement the `droplevel` method","messagePattern":"Please implement the `droplevel` method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/data/utils/sepdf.py","lineNumber":127,"sourceCode":"                        col_name = col_name[0]\n                    self._df_dict[_df_dict_key] = df.to_frame(col_name)\n                else:\n                    df_copy = df.copy()  # avoid changing df\n                    df_copy.columns = pd.MultiIndex.from_tuples([(*col_name, *idx) for idx in df.columns.to_list()])\n                    self._df_dict[_df_dict_key] = df_copy\n\n    def __delitem__(self, item: str):\n        del self._df_dict[item]\n        self._update_join()\n\n    def __contains__(self, item):\n        return item in self._df_dict\n\n    def __len__(self):\n        return len(self._df_dict[self.join])\n\n    def droplevel(self, *args, **kwargs):\n        raise NotImplementedError(f\"Please implement the `droplevel` method\")\n\n    @property\n    def columns(self):\n        dfs = []\n        for k, df in self._df_dict.items():\n            df = df.head(0)\n            df.columns = pd.MultiIndex.from_product([[k], df.columns])\n            dfs.append(df)\n        return pd.concat(dfs, axis=1).columns\n\n    # Useless methods\n    @staticmethod\n    def merge(df_dict: Dict[str, pd.DataFrame], join: str):\n        all_df = df_dict[join]\n        for k, df in df_dict.items():\n            if k != join:\n                all_df = all_df.join(df)\n        return all_df","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/data/utils/sepdf.py#L109-L145","documentation":"SepDataFrame deliberately stubs out pandas' DataFrame.droplevel with NotImplementedError. SepDataFrame is a container that keeps one DataFrame per instrument group in _df_dict and emulates the pandas API lazily; droplevel was never implemented because removing a MultiIndex level has ambiguous semantics across the separated frames.","triggerScenarios":"Calling .droplevel(...) on an object returned by the high-frequency loader (which wraps data in SepDataFrame), e.g. sdf.droplevel(0) or df.droplevel('instrument') where df is a SepDataFrame patched to pass isinstance checks as pd.DataFrame.","commonSituations":"Generic pandas code that flattens MultiIndex columns/rows after loading data; using a SepDataFrame where a real DataFrame is expected because the module patches builtins.isinstance to make it pass isinstance(x, pd.DataFrame).","solutions":["Materialize a real DataFrame first: df = sdf._df_dict[sdf.join] (or select the group you need) and then call droplevel on it.","Subclass SepDataFrame and implement droplevel to apply it to every frame in _df_dict and update the join key.","Restructure your code to avoid droplevel on this container (select with .loc(axis=1)[cols] instead)."],"exampleFix":"// before\nflat = sdf.droplevel(0)  # NotImplementedError\n\n// after\nflat = sdf._df_dict[sdf.join].droplevel(0)","handlingStrategy":"type-guard","validationCode":"if hasattr(df, \"_df_dict\"):  # SepDataFrame\n    df = df._df_dict[df.join]  # materialize real pandas frame\ndf.droplevel(0)","typeGuard":"from qlib.contrib.data.utils import SepDataFrame\n\ndef is_sep_dataframe(x) -> bool:\n    return hasattr(x, \"_df_dict\") and hasattr(x, \"join\")","tryCatchPattern":"try:\n    out = df.droplevel(0)\nexcept NotImplementedError:\n    # SepDataFrame stub: fall back to materializing the underlying frame\n    out = df._df_dict[df.join].droplevel(0)","preventionTips":["Remember qlib patches isinstance so SepDataFrame passes isinstance(x, pd.DataFrame) — check for _df_dict instead.","Materialize SepDataFrame to a real DataFrame before exotic pandas operations.","Wrap generic pandas helpers to accept SepDataFrame by converting first."],"tags":["qlib","sepdf","pandas","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}