code: def _data_to_bin(
      self,
      df: pd.DataFrame,
      calendar_list: List[pd.Timestamp],
      features_dir: Path,
  ):
      if df.empty:
          logger.warning(f"{features_dir.name} data is None or empty")
          return
      if not calendar_list:
          logger.warning("calendar_list is empty")
          return
      # align index
      _df = self.data_merge_calendar(df, calendar_list)
      if _df.empty:
          logger.warning(
              f"{features_dir.name} data is not in calendars"
          )
          return
      # used when creating a bin file
      date_index = self.get_datetime_index(_df, calendar_list)
      for field in self.get_dump_fields(_df.columns):
          bin_path = features_dir.joinpath(
              f"{field.lower()}.{self.freq}{self.DUMP_FILE_SUFFIX}"
          )
          if field not in _df.columns:
              continue
          if bin_path.exists() and self._mode == self.UPDATE_MODE:
              # update
              with bin_path.open("ab") as fp:
                  np.array(_df[field]).astype("<f").tofile(fp)
          else:
              # append; self._mode == self.ALL_MODE or not bin_path.exists()
              np.hstack([date_index, _df[field]]).astype("<f").tofile(
                  str(bin_path.resolve())
              )
  
imports: import abc
  import shutil
  import traceback
  from pathlib import Path
  from typing import Iterable, List, Union
  from functools import partial
  from concurrent.futures import ThreadPoolExecutor, as_completed, ProcessPoolExecutor
  import fire
  import numpy
  import pandas
  from tqdm import tqdm
  from loguru import logger
  from qlib.utils import fname_to_code, code_to_fname
label_desc: Use image node_id 14 for calling the DumpDataBase obj's underlying member method code with example usage: obj._data_to_bin(df, calendar_list, features_dir) without return types