Repository: microsoft/qlib
File: qlib/data/dataset/__init__.py (Python)

Code before:
            indices = np.concatenate([np.full((self.step_len - len(indices),), np.nan), indices])

        if self.fillna_type == "ffill":
            indices = np_ffill(indices)
        elif self.fillna_type == "ffill+bfill":
            indices = np_ffill(np_ffill(indices)[::-1])[::-1]
        else:
            assert self.fillna_type == "none"
        return indices

    def _get_row_col(self, idx) -> Tuple[int]:
        """
        get the col index and row index of a given sample index in self.idx_df

        Parameters
        ----------
        idx :
            the input of  `__getitem__`

        Returns
        -------
        Tuple[int]:
            the row and col index
        """
        # The the right row number `i` and col number `j` in idx_df
        if isinstance(idx, (int, np.integer)):
            real_idx = idx
            if 0 <= real_idx < len(self.idx_map):
                i, j = self.idx_map[real_idx]  # TODO: The performance of this line is not good
            else:
                raise KeyError(f"{real_idx} is out of [0, {len(self.idx_map)})")
        elif isinstance(idx, tuple):
            # <TSDataSampler object>["datetime", "instruments"]
            date, inst = idx
            date = pd.Timestamp(date)
            i = bisect.bisect_right(self.idx_df.index, date) - 1
            # NOTE: This relies on the idx_df columns sorted in `__init__`
            j = bisect.bisect_left(self.idx_df.columns, inst)
        else:
            raise NotImplementedError(f"This type of input is not supported")
        return i, j

    def __getitem__(self, idx: Union[int, Tuple[object, str], List[int]]):
        """
        # We have two method to get the time-series of a sample
        tsds is a instance of TSDataSampler

        # 1) sample by int index directly
        tsds[len(tsds) - 1]

        # 2) sample by <datetime,instrument> index

Review comment (suggestion):
For line 445,
`The DataFrame with <datetime, DataFrame>`  -> 
```
A DataFrame with index in order <instrument, datetime>
e.g.
                          RSQR5     RESI5     WVMA5    LABEL0
instrument datetime
SH600000   2017-01-03  0.016389  0.461632 -1.154788 -0.048056
           2017-01-04  0.884545 -0.110597 -1.059332 -0.030139
           2017-01-05  0.507540 -0.535493 -1.099665 -0.644983
           2017-01-06 -1.267771 -0.669685 -1.636733  0.295366
           2017-01-09  0.339346  0.074317 -0.984989  0.765540
```

Code after:
        ----------
        data : pd.DataFrame
            A DataFrame with index in order <instrument, datetime>

                                      RSQR5     RESI5     WVMA5    LABEL0
            instrument datetime
            SH600000   2017-01-03  0.016389  0.461632 -1.154788 -0.048056
                       2017-01-04  0.884545 -0.110597 -1.059332 -0.030139
                       2017-01-05  0.507540 -0.535493 -1.099665 -0.644983
                       2017-01-06 -1.267771 -0.669685 -1.636733  0.295366
                       2017-01-09  0.339346  0.074317 -0.984989  0.765540

        Returns
        -------
        Tuple[pd.DataFrame, dict]:
            1) the first element:  reshape the original index into a <datetime(row), instrument(column)> 2D dataframe
                instrument SH600000 SH600008 SH600009 SH600010 SH600011 SH600015  ...
                datetime
                2017-01-03        0      242      473      717      NaN      974  ...
                2017-01-04        1      243      474      718      NaN      975  ...
                2017-01-05        2      244      475      719      NaN      976  ...
                2017-01-06        3      245      476      720      NaN      977  ...
            2) the second element:  {<original index>: <row, col>}
        """
        # object incase of pandas converting int to float
        idx_df = pd.Series(range(data.shape[0]), index=data.index, dtype=object)
        idx_df = lazy_sort_index(idx_df.unstack())
        # NOTE: the correctness of `__getitem__` depends on columns sorted here
        idx_df = lazy_sort_index(idx_df, axis=1).T

        idx_map = {}
        for i, (_, row) in enumerate(idx_df.iterrows()):
            for j, real_idx in enumerate(row):
                if not np.isnan(real_idx):
                    idx_map[real_idx] = (i, j)
        return idx_df, idx_map

    @property
    def empty(self):
        return len(self) == 0

    def _get_indices(self, row: int, col: int) -> np.array:
        """
        get series indices of self.data_arr from the row, col indices of self.idx_df

        Parameters
        ----------
        row : int
            the row in self.idx_df
        col : int
            the col in self.idx_df