code: def _concat_compat(to_concat, axis=0):
      """
      provide concatenation of an array of arrays each of which is a single
      'normalized' dtypes (in that for example, if it's object, then it is a
      non-datetimelike and provide a combined dtype for the resulting array that
      preserves the overall dtype if possible)
  
      Parameters
      ----------
      to_concat : array of arrays
      axis : axis to provide concatenation
  
      Returns
      -------
      a single array, preserving the combined dtypes
      """
  
      # filter empty arrays
      # 1-d dtypes always are included here
      def is_nonempty(x):
          try:
              return x.shape[axis] > 0
          except Exception:
              return True
  
      nonempty = [x for x in to_concat if is_nonempty(x)]
  
      # If all arrays are empty, there's nothing to convert, just short-cut to
      # the concatenation, #3121.
      #
      # Creating an empty array directly is tempting, but the winnings would be
      # marginal given that it would still require shape & dtype calculation and
      # np.concatenate which has them both implemented is compiled.
  
      typs = get_dtype_kinds(to_concat)
      _contains_datetime = any(
          typ.startswith("datetime") for typ in typs
      )
      _contains_period = any(typ.startswith("period") for typ in typs)
  
      if "category" in typs:
          # this must be priort to _concat_datetime,
          # to support Categorical + datetime-like
          return _concat_categorical(to_concat, axis=axis)
  
      elif (
          _contains_datetime or "timedelta" in typs or _contains_period
      ):
          return _concat_datetime(to_concat, axis=axis, typs=typs)
  
      # these are mandated to handle empties as well
      elif "sparse" in typs:
          return _concat_sparse(to_concat, axis=axis, typs=typs)
  
      extensions = [is_extension_array_dtype(x) for x in to_concat]
      if any(extensions) and axis == 1:
          to_concat = [
              np.atleast_2d(x.astype("object")) for x in to_concat
          ]
  
      if not nonempty:
          # we have all empties, but may need to coerce the result dtype to
          # object if we have non-numeric type operands (numpy would otherwise
          # cast this to float)
          typs = get_dtype_kinds(to_concat)
          if len(typs) != 1:
              if not len(typs - {"i", "u", "f"}) or not len(
                  typs - {"bool", "i", "u"}
              ):
                  # let numpy coerce
                  pass
              else:
                  # coerce to object
                  to_concat = [x.astype("object") for x in to_concat]
  
      return np.concatenate(to_concat, axis=axis)
  
file_path: catboost/contrib/python/pandas/py2/pandas/core/dtypes/concat.py
imports: import numpy
  from pandas._libs import tslib, tslibs
  from pandas.core.dtypes.common import _NS_DTYPE, _TD_DTYPE, is_bool_dtype, is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_dtype_equal, is_extension_array_dtype, is_object_dtype, is_sparse, is_timedelta64_dtype
  from pandas.core.dtypes.generic import ABCDatetimeArray, ABCDatetimeIndex, ABCIndexClass, ABCPeriodIndex, ABCRangeIndex, ABCSparseDataFrame, ABCTimedeltaIndex
  from pandas import compat
label_desc: Use image node_id 4 for calling a global function with example usage: _concat_compat(to_concat, axis) and returns: np, _concat_categorical, unknown, _concat_datetime, True, _concat_sparse