class_docstr: Hashing data storage for datahanlder
  - The default data storage pandas.DataFrame is too slow when randomly accessing one stock's data
  - HashingStockStorage hashes the multiple stocks' data(pandas.DataFrame) by the key `stock_id`.
  - HashingStockStorage hashes the pandas.DataFrame into a dict, whose key is the stock_id(str) and value this stock data(panda.DataFrame), it has the following format:
      {
          stock1_id: stock1_data,
          stock2_id: stock2_data,
          ...
          stockn_id: stockn_data,
      }
  - By the `fetch` method, users can access any stock data with much lower time cost than default data storage
class_docstr_tok: ["Hashing","data","storage","for","datahanlder","-","The","default","data","storage","pandas.DataFrame","is","too","slow","when","randomly","accessing","one","stock","'s","data","-","HashingStockStorage","hashes","the","multiple","stocks","'","data","(","pandas.DataFrame",")","by","the","key","`","stock_id","`",".","-","HashingStockStorage","hashes","the","pandas.DataFrame","into","a","dict",",","whose","key","is","the","stock_id","(","str",")","and","value","this","stock","data","(","panda.DataFrame",")",",","it","has","the","following","format",":","{","stock1_id",":","stock1_data",",","stock2_id",":","stock2_data",",","...","stockn_id",":","stockn_data",",","}","-","By","the","`","fetch","`","method",",","users","can","access","any","stock","data","with","much","lower","time","cost","than","default","data","storage"]
code: def fetch(
      self,
      selector: Union[pd.Timestamp, slice, str] = slice(None, None),
      level: Union[str, int] = "datetime",
      col_set: Union[str, List[str]] = DataHandler.CS_ALL,
      fetch_orig: bool = True,
  ) -> pd.DataFrame:
      fetch_stock_df_list = list(
          self._fetch_hash_df_by_stock(
              selector=selector, level=level
          ).values()
      )
      for _index, stock_df in enumerate(fetch_stock_df_list):
          fetch_col_df = fetch_df_by_col(df=stock_df, col_set=col_set)
          fetch_index_df = fetch_df_by_index(
              df=fetch_col_df,
              selector=selector,
              level=level,
              fetch_orig=fetch_orig,
          )
          fetch_stock_df_list[_index] = fetch_index_df
      if len(fetch_stock_df_list) == 0:
          index_names = (
              ("instrument", "datetime")
              if self.stock_level == 0
              else ("datetime", "instrument")
          )
          return pd.DataFrame(
              index=pd.MultiIndex.from_arrays(
                  [[], []], names=index_names
              ),
              columns=self.columns,
              dtype=np.float32,
          )
      elif len(fetch_stock_df_list) == 1:
          return fetch_stock_df_list[0]
      else:
          return pd.concat(
              fetch_stock_df_list, sort=False, copy=~fetch_orig
          )
  
file_path: qlib/qlib/data/dataset/storage.py
imports: import pandas
  import numpy
  from .handler import DataHandler
  from typing import Union, List, Callable
  from .utils import get_level_index, fetch_df_by_index, fetch_df_by_col
label_desc: Use image node_id 4 for calling the HashingStockStorage obj's underlying member method code with example usage: obj.fetch(selector, level, col_set, fetch_orig) and returns: pd, fetch_stock_df_list, pd