code: def _process_column_initial(
      X_col, nonmissings, processing, min_unique_continuous
  ):
      # called under: fit
  
      if issubclass(X_col.dtype.type, np.floating):
          missings = np.isnan(X_col)
          if missings.any():
              nonmissings = ~missings
              X_col = X_col[nonmissings]
      elif X_col.dtype.type is np.object_:
          X_col = _densify_object_ndarray(X_col)
  
      uniques, indexes, counts = np.unique(
          X_col, return_inverse=True, return_counts=True
      )
  
      if issubclass(uniques.dtype.type, np.floating):
          floats = uniques.astype(np.float64, copy=False)
          uniques = floats.astype(np.unicode_)
      else:
          uniques = uniques.astype(np.unicode_, copy=False)
          try:
              # we rely here on there being a round trip format within this language from float64 to text to float64
  
              # TODO: does this work if there are spaces or bools?
  
              floats = uniques.astype(dtype=np.float64)
          except ValueError:
              floats = None
  
      if min_unique_continuous is not None and floats is not None:
          # floats can have more than one string representation, so run unique again to check if we have
          # min_unique_continuous unique float64s in binary representation
          if min_unique_continuous <= len(np.unique(floats)):
              floats = floats[
                  indexes
              ]  # expand from the unique floats to expanded floats
              if nonmissings is not None:
                  floats_tmp = np.full(
                      len(nonmissings), np.nan, dtype=np.float64
                  )
                  np.place(floats_tmp, nonmissings, floats)
                  floats = floats_tmp
  
              return floats, None
  
      # TODO: we need to move this re-ordering functionality to EBMPreprocessor.fit(...) and return a
      # np.unicode_ array here.  There are two issues with keeping it here
      #   1) If the user wants 'nominal_prevalence' in a DP model, then we need to order the prevalence
      #      by the publically visible noisy weights rather than the private non-noisy prevalences,
      #      but we don't have access to the noisy weights here.  We haven't documented 'nominal_prevalence'
      #      yet, so nobody should be using it yet, but before we make it public we need to solve this issue
      #   2) If we someday want to have an 'eval_set' that has a separate X_eval, then we'll need
      #      two iterators that operate on different X's.  If that happens then the categories dictionary
      #      needs to be synchronized, so we need access to all the possible categories which is not available
      #      here
      # Since we only really care about speed during predict time, and at predict time we already have a
      # categories dictionary, moving this to EBMPreprocessor.fit(...) won't cause any performance issues
      # but it's a bit more complicated.  Also, we need to think through how we handle categoricals from
      # pandas.  We can't return an np.unicode_ array there since then we'd loose the ordering that pandas
      # gives us, which at a minimum is required for ordinals, and is nice to preserve for nominals because
      # it gives the user an easy way to order the nominals on the graph and in the models (for model editing).
      #
      # Alternatively, if we decide to expose the integer bag definitions instead of having an eval_set then
      # we could probably just keep the ordering here and then re-order them again in
      # EBMPreprocessor.fit(...) for DP models.  If we destroy the information about prevalence and resort
      # by noisy prevalence then that would be ok.
  
      # TODO: add a callback function option here that allows the caller to sort, remove, combine
      if processing == "nominal_prevalence":
          if floats is None:
              categories = [
                  (-item[0], item[1]) for item in zip(counts, uniques)
              ]
          else:
              categories = [
                  (-item[0], item[1], item[2])
                  for item in zip(counts, floats, uniques)
              ]
          categories.sort()
          categories = [x[-1] for x in categories]
      elif processing != "nominal_alphabetical" and floats is not None:
          categories = [
              (item[0], item[1]) for item in zip(floats, uniques)
          ]
          categories.sort()
          categories = [x[1] for x in categories]
      else:
          categories = uniques.tolist()
          categories.sort()
  
      categories = dict(zip(categories, count(1)))
      mapping = np.fromiter(
          (categories[val] for val in uniques),
          np.int64,
          count=len(uniques),
      )
      encoded = mapping[indexes]
  
      if nonmissings is not None:
          encoded_tmp = np.zeros(len(nonmissings), dtype=np.int64)
          np.place(encoded_tmp, nonmissings, encoded)
          encoded = encoded_tmp
  
      return encoded, categories
  
imports: from collections import Counter
  from itertools import count
  import numpy
  import numpy.ma
  import logging
label_desc: Use image node_id 2 for calling a global function with example usage: _process_column_initial(X_col, nonmissings, processing, min_unique_continuous) and returns: encoded,  categories, floats,  None