code: def format_entities_from_col(
      defs: HyperBindings,
      cat_lookup: Dict[str, str],
      drop_na: bool,
      engine: Engine,
      col_name: str,
      df_with_col: DataframeLike,
      meta: pd.DataFrame,
      debug: bool,
  ) -> DataframeLocalLike:
      """
      For unique v in column col, create [{col: str(v), title: str(v), nodetype: col, nodeid: `<cat><delim><v>`}]
          - respect drop_na
          - respect colname overrides
          - receive+return pd.DataFrame / cudf.DataFrame depending on engine
      """
      logger.debug(
          "@format_entities: [drop: %s], %s / %s",
          drop_na,
          col_name,
          [c for c in df_with_col],
      )
  
      try:
          df_with_col_pre = (
              df_with_col[col_name].dropna()
              if drop_na
              else df_with_col[col_name]
          )
          if debug and engine in [Engine.DASK, Engine.DASK_CUDF]:
              df_with_col_pre = df_with_col_pre.persist()
              logger.debug(
                  "col [ %s ] entities with dropna [ %s ]: %s",
                  col_name,
                  drop_na,
                  df_with_col_pre.compute(),
              )
          try:
              unique_vals = df_with_col_pre.drop_duplicates()
          except:
              unique_vals = df_with_col_pre.astype(
                  str
              ).drop_duplicates()
              logger.warning(
                  "Coerced col %s to string type for entity names",
                  col_name,
              )
          unique_safe_val_strs = (
              unique_vals.astype(str).fillna(defs.null_val).astype(str)
          )
      except NotImplementedError:
          logger.warning(
              "Dropped col %s from entity list due to errors"
          )
          unique_vals = mt_series(engine)
          unique_safe_val_strs = (
              unique_vals.astype(str).fillna(defs.null_val).astype(str)
          )
  
      if debug and engine in [Engine.DASK, Engine.DASK_CUDF]:
          unique_vals = unique_vals.persist()
          logger.debug("unique_vals: %s", unique_vals.compute())
  
      base_df = unique_vals.rename(col_name).to_frame()
      base_df = base_df.assign(
          **{
              defs.title: unique_safe_val_strs,
              defs.node_type: col_name,
              defs.category: col2cat(cat_lookup, col_name),
              defs.node_id: (col2cat(cat_lookup, col_name) + defs.delim)
              + unique_safe_val_strs,
          }
      )
  
      if debug and engine in [Engine.DASK, Engine.DASK_CUDF]:
          base_df = base_df.persist()
          logger.debug("base_df1: %s", base_df.compute())
  
      missing_cols: List = [c for c in meta.columns if c not in base_df]
      base_df = base_df.assign(**{c: np.nan for c in missing_cols})
      logger.debug("==== BASE 2 ====")
      if debug and engine in [Engine.DASK, Engine.DASK_CUDF]:
          base_df = base_df.persist()
          logger.debug("base_df2: %s", base_df.compute())
          logger.debug(
              "needs conversions: %s",
              [
                  (
                      c,
                      base_df[c].dtype.name,
                      meta[c].dtype.name,  # type: ignore
                  )
                  for c in missing_cols
              ],
          )
          for c in base_df:
              logger.debug(
                  "test base_df2 col [ %s ]: %s", c, base_df[c].dtype
              )
              logger.debug(
                  "base_df2[ %s ]: %s", c, base_df[c].compute()
              )
              logger.debug(
                  "convert [ %s ] %s -> %s",
                  c,
                  base_df[c].dtype.name,
                  meta[c].dtype.name,
              )
              logger.debug("orig: %s", base_df[c].compute())
              logger.debug(
                  "was a missing col needing coercion: %s",
                  c in missing_cols,
              )
              if c in missing_cols:
                  logger.debug(
                      "coerced 1: %s",
                      coerce_col_safe(
                          base_df[c], meta[c].dtype
                      ).compute(),
                  )
                  logger.debug(
                      "coerced 2: %s",
                      base_df.assign(
                          **{
                              c: coerce_col_safe(
                                  base_df[c], meta[c].dtype
                              )
                          }
                      ).compute(),
                  )
      base_as_meta_df = base_df.assign(
          **{
              c: coerce_col_safe(base_df[c], meta[c].dtype)
              if base_df[c].dtype.name != meta[c].dtype.name  # type: ignore
              else base_df[c]
              for c in missing_cols
          }
      )
      logger.debug("==== BASE 3 ====")
      if debug and engine in [Engine.DASK, Engine.DASK_CUDF]:
          base_as_meta_df = base_as_meta_df.persist()
          for c in base_df:
              logger.debug(
                  "test base_df3 col [ %s ]: %s -> %s",
                  c,
                  base_df[c].dtype,
                  base_as_meta_df[c].dtype,
              )
              logger.debug(
                  "base_df3[ %s ]: %s", c, base_as_meta_df[c].compute()
              )
  
      return base_as_meta_df
  
imports: from typing import TYPE_CHECKING, Any, Dict, List, Optional
  from .Engine import Engine, DataframeLike, DataframeLocalLike
  import numpy, pandas, pyarrow, sys
  from .util import setup_logger
label_desc: Use image node_id 5 for calling a global function with example usage: format_entities_from_col(defs, cat_lookup, drop_na, engine, col_name, df_with_col, meta, debug) and returns: base_as_meta_df