code: def factorize_array(
      values: np.ndarray,
      use_na_sentinel: bool = True,
      size_hint: int | None = None,
      na_value: object = None,
      mask: npt.NDArray[np.bool_] | None = None,
  ) -> tuple[npt.NDArray[np.intp], np.ndarray]:
      """
      Factorize a numpy array to codes and uniques.
  
      This doesn't do any coercion of types or unboxing before factorization.
  
      Parameters
      ----------
      values : ndarray
      use_na_sentinel : bool, default True
          If True, the sentinel -1 will be used for NaN values. If False,
          NaN values will be encoded as non-negative integers and will not drop the
          NaN from the uniques of the values.
      size_hint : int, optional
          Passed through to the hashtable's 'get_labels' method
      na_value : object, optional
          A value in `values` to consider missing. Note: only use this
          parameter when you know that you don't have any values pandas would
          consider missing in the array (NaN for float data, iNaT for
          datetimes, etc.).
      mask : ndarray[bool], optional
          If not None, the mask is used as indicator for missing values
          (True = missing, False = valid) instead of `na_value` or
          condition "val != val".
  
      Returns
      -------
      codes : ndarray[np.intp]
      uniques : ndarray
      """
      original = values
      if values.dtype.kind in "mM":
          # _get_hashtable_algo will cast dt64/td64 to i8 via _ensure_data, so we
          #  need to do the same to na_value. We are assuming here that the passed
          #  na_value is an appropriately-typed NaT.
          # e.g. test_where_datetimelike_categorical
          na_value = iNaT
  
      hash_klass, values = _get_hashtable_algo(values)
  
      table = hash_klass(size_hint or len(values))
      uniques, codes = table.factorize(
          values,
          na_sentinel=-1,
          na_value=na_value,
          mask=mask,
          ignore_na=use_na_sentinel,
      )
  
      # re-cast e.g. i8->dt64/td64, uint8->bool
      uniques = _reconstruct_data(uniques, original.dtype, original)
  
      codes = ensure_platform_int(codes)
      return codes, uniques
  
imports: from __future__ import annotations
  import decimal
  import operator
  from textwrap import dedent
  from typing import TYPE_CHECKING, Literal, cast
  import warnings
  import numpy
  from pandas._libs import algos, hashtable, iNaT, lib
  from pandas._typing import AnyArrayLike, ArrayLike, ArrayLikeT, AxisInt, DtypeObj, TakeIndexer, npt
  from pandas.util._decorators import doc
  from pandas.util._exceptions import find_stack_level
  from pandas.core.dtypes.cast import construct_1d_object_array_from_listlike, np_find_common_type
  from pandas.core.dtypes.common import ensure_float64, ensure_object, ensure_platform_int, is_array_like, is_bool_dtype, is_complex_dtype, is_dict_like, is_extension_array_dtype, is_float, is_float_dtype, is_integer, is_integer_dtype, is_list_like, is_object_dtype, is_signed_integer_dtype, needs_i8_conversion
  from pandas.core.dtypes.concat import concat_compat
  from pandas.core.dtypes.dtypes import BaseMaskedDtype, CategoricalDtype, ExtensionDtype, NumpyEADtype
  from pandas.core.dtypes.generic import ABCDatetimeArray, ABCExtensionArray, ABCIndex, ABCMultiIndex, ABCSeries, ABCTimedeltaArray
  from pandas.core.dtypes.missing import isna, na_value_for_dtype
  from pandas.core.array_algos.take import take_nd
  from pandas.core.construction import array, ensure_wrapped_if_datetimelike, extract_array
  from pandas.core.indexers import validate_indices
label_desc: Use image node_id 10 for calling a global function with example usage: factorize_array(values, use_na_sentinel, size_hint, na_value, mask) and returns: codes,  uniques