code: def detect_types(
      X,
      type_hints=None,
      max_cat_cardinality="auto",
      dirty_float_threshold=0.9,
      near_constant_threshold=0.95,
      target_col=None,
      verbose=0,
  ):
      """Detect types of dataframe columns.
  
      Columns are labeled as one of the following types:
      'continuous', 'categorical', 'low_card_int', 'dirty_float',
      'free_string', 'date', 'useless'
  
      Pandas categorical variables, strings and integers of low cardinality and
      float values with two columns are labeled as categorical.
      Integers of high cardinality are labeled as continuous.
      Integers of intermediate cardinality are labeled as "low_card_int".
      Float variables that sometimes take string values are labeled "dirty_float"
      String variables with many unique values are labeled "free_text"
      (and currently not processed by dabl).
      Date types are labeled as "date" (and currently not processed by dabl).
      Anything that is constant, nearly constant, detected as an integer index,
      or doesn't match any of the above categories is labeled "useless".
  
      Parameters
      ----------
      X : dataframe
          input
  
      max_cat_cardinality: int or 'auto', default='auto'
          Maximum number of distinct integer or string values for a column
          to be considered categorical. 'auto' is ``max(42, n_samples/100)``.
  
      dirty_float_threshold : float, default=.9
          The fraction of floats required in a dirty continuous
          column before it's considered "useless" or categorical
          (after removing top 5 string values)
  
      target_col : string, int or None
          Specifies the target column in the data, if any.
          Target columns are never dropped.
  
      verbose : int
          How verbose to be
  
      Returns
      -------
      res : dataframe, shape (n_columns, 7)
          Boolean dataframe of detected types. Rows are columns in input X,
          columns are possible types (see above).
      """
      # TODO detect top coding
      # TODO subsample large datsets? one level up?
      if not isinstance(X, pd.DataFrame):
          raise TypeError(
              "X is not a dataframe. Convert or call `clean`."
          )
      if not X.index.is_unique:
          raise ValueError(
              "Non-unique index found. Reset index or call clean."
          )
      duplicated = X.columns.duplicated()
      if duplicated.any():
          raise ValueError(
              "Duplicate Columns: {}".format(X.columns[duplicated])
          )
  
      if type_hints is None:
          type_hints = dict()
  
      types_series = X.apply(
          lambda col: detect_type_series(
              col,
              max_cat_cardinality=max_cat_cardinality,
              near_constant_threshold=near_constant_threshold,
              target_col=target_col,
              dirty_float_threshold=dirty_float_threshold,
          )
      )
  
      types_series[types_series.isin(USELESS_TYPES)] = "useless"
  
      for t in type_hints:
          if t in X.columns:
              types_series[t] = type_hints[t]
  
      known_types = [
          "continuous",
          "dirty_float",
          "low_card_int_ordinal",
          "low_card_int_categorical",
          "categorical",
          "date",
          "free_string",
          "useless",
      ]
      if X.empty:
          return pd.DataFrame(columns=known_types, dtype=bool)
      if not set(np.array(types_series)).issubset(known_types):
          raise RuntimeError("Unexpected types.")
      res = pd.DataFrame({t: types_series == t for t in known_types})
      assert (X.columns == res.index).all()
  
      assert np.all(res.sum(axis=1) == 1)
  
      assert (types_series == res.idxmax(axis=1)).all()
  
      if verbose >= 1:
          print("Detected feature types:")
          print(res.sum())
      return res
  
imports: from importlib.metadata import version
  from joblib import hash
  import warnings
  from warnings import warn
  import numpy
  import pandas
  from sklearn.base import BaseEstimator, TransformerMixin
  from sklearn.compose import make_column_transformer, ColumnTransformer
  from sklearn.impute import SimpleImputer
  from sklearn.pipeline import make_pipeline
  from sklearn.preprocessing import OneHotEncoder, StandardScaler
  from sklearn.utils.validation import check_is_fitted
label_desc: Use image node_id 12 for calling a global function with example usage: detect_types(X, type_hints, max_cat_cardinality, dirty_float_threshold, near_constant_threshold, target_col, verbose) and returns: res, pd