code: def check_dataframe(
      df: pd.DataFrame,
      check_y: bool = True,
      covariates=None,
      regressors=None,
      events=None,
      seasonalities=None,
      future: Optional[bool] = None,
  ) -> Tuple[pd.DataFrame, List, List]:
      """Performs basic data sanity checks and ordering,
      as well as prepare dataframe for fitting or predicting.
  
      Parameters
      ----------
          df : pd.DataFrame
              containing column ``ds``
          check_y : bool
              if df must have series values
              set to True if training or predicting with autoregression
          covariates : list or dict
              covariate column names
          regressors : list or dict
              regressor column names
          events : list or dict
              event column names
          seasonalities : list or dict
              seasonalities column names
          future : bool
              if df is a future dataframe
  
      Returns
      -------
          pd.DataFrame or dict
              checked dataframe
      """
      df, _, _, _ = prep_or_copy_df(df)
      if df.groupby("ID").size().min() < 1:
          raise ValueError("Dataframe has no rows.")
      if "ds" not in df:
          raise ValueError(
              "Dataframe must have columns 'ds' with the dates."
          )
      if df["ds"].isnull().any():
          raise ValueError("Found NaN in column ds.")
      if not np.issubdtype(df["ds"].to_numpy().dtype, np.datetime64):
          df["ds"] = pd.to_datetime(
              df.loc[:, "ds"], utc=True
          ).dt.tz_convert(None)
      if (
          df.groupby("ID")
          .apply(lambda x: x.duplicated("ds").any())
          .any()
      ):
          raise ValueError(
              "Column ds has duplicate values. Please remove duplicates."
          )
  
      regressors_to_remove = []
      lag_regressors_to_remove = []
      columns = []
      if check_y:
          columns.append("y")
      if regressors is not None:
          for reg in regressors:
              if len(df[reg].unique()) < 2:
                  log.warning(
                      "Encountered future regressor with only unique values in training set across all IDs."
                      "Automatically removed variable."
                  )
                  regressors_to_remove.append(reg)
          if isinstance(regressors, list):
              columns.extend(regressors)
          else:  # treat as dict
              columns.extend(regressors.keys())
      if covariates is not None:
          for covar in covariates:
              if len(df[covar].unique()) < 2:
                  log.warning(
                      "Encountered lagged regressor with only unique values in training set across all IDs."
                      "Automatically removed variable."
                  )
                  lag_regressors_to_remove.append(covar)
          if isinstance(covariates, list):
              columns.extend(covariates)
          else:  # treat as dict
              columns.extend(covariates.keys())
      if events is not None:
          if isinstance(events, list):
              columns.extend(events)
          else:  # treat as dict
              columns.extend(events.keys())
      if seasonalities is not None:
          for season in seasonalities.periods:
              condition_name = seasonalities.periods[
                  season
              ].condition_name
              if condition_name is not None:
                  if (
                      not df[condition_name].isin([True, False]).all()
                      and not df[condition_name].between(0, 1).all()
                  ):
                      raise ValueError(
                          f"Condition column {condition_name} must be boolean or numeric between 0 and 1."
                      )
                  columns.append(condition_name)
      for name in columns:
          if name not in df:
              raise ValueError(
                  f"Column {name!r} missing from dataframe"
              )
          if df.loc[df.loc[:, name].notnull()].shape[0] < 1:
              raise ValueError(
                  f"Dataframe column {name!r} only has NaN rows."
              )
          if not np.issubdtype(df[name].dtype, np.number):
              df[name] = pd.to_numeric(df[name])
          if np.isinf(df.loc[:, name].values).any():
              df.loc[:, name] = df[name].replace(
                  [np.inf, -np.inf], np.nan
              )
          if df.loc[df.loc[:, name].notnull()].shape[0] < 1:
              raise ValueError(
                  f"Dataframe column {name!r} only has NaN rows."
              )
  
      if future:
          return df, regressors_to_remove, lag_regressors_to_remove
      if len(regressors_to_remove) > 0:
          regressors_to_remove = list(set(regressors_to_remove))
          df = df.drop(regressors_to_remove, axis=1)
          assert df is not None
      if len(lag_regressors_to_remove) > 0:
          lag_regressors_to_remove = list(set(lag_regressors_to_remove))
          df = df.drop(lag_regressors_to_remove, axis=1)
          assert df is not None
      return df, regressors_to_remove, lag_regressors_to_remove
  
imports: from __future__ import annotations
  import logging
  import math
  from collections import OrderedDict
  from dataclasses import dataclass
  from typing import TYPE_CHECKING, List, Optional, Tuple
  import numpy
  import pandas
label_desc: Use image node_id 10 for calling a global function with example usage: check_dataframe(df, check_y, covariates, regressors, events, seasonalities, future) and returns: df,  regressors_to_remove,  lag_regressors_to_remove, df,  regressors_to_remove,  lag_regressors_to_remove