code: def is_nested_dataframe(obj, return_metadata=False, var_name="obj"):
      """Check whether the input is a nested DataFrame.
  
      To allow for a mixture of nested and primitive columns types the
      the considers whether any column is a nested np.ndarray or pd.Series.
  
      Column is consider nested if any cells in column have a nested structure.
  
      Parameters
      ----------
      X: Input that is checked to determine if it is a nested DataFrame.
  
      Returns
      -------
      bool: Whether the input is a nested DataFrame
      """
      # If not a DataFrame we know is_nested_dataframe is False
      if not isinstance(obj, pd.DataFrame):
          msg = f"{var_name} must be a pd.DataFrame, found {type(obj)}"
          return _ret(False, msg, None, return_metadata)
      # Otherwise we'll see if any column has a nested structure in first row
      else:
          if not all([i == "object" for i in obj.dtypes]):
              msg = f"{var_name} All columns must be object, found {type(obj)}"
              return _ret(False, msg, None, return_metadata)
  
          if not are_columns_nested(obj):
              msg = f"{var_name} entries must be pd.Series"
              return _ret(False, msg, None, return_metadata)
  
      # check that columns are unique
      if not obj.columns.is_unique:
          msg = f"{var_name} must have unique column indices, but found {obj.columns}"
          return _ret(False, msg, None, return_metadata)
  
      # Check instance index is unique
      if not obj.index.is_unique:
          msg = (
              f"The instance index of {var_name} must be unique, "
              f"but found duplicates. Use {var_name}.duplicated() "
              f"to find the duplicates."
          )
          return _ret(False, msg, None, return_metadata)
  
      metadata = dict()
      if _req("is_univariate", return_metadata):
          metadata["is_univariate"] = obj.shape[1] < 2
      if _req("n_instances", return_metadata):
          metadata["n_instances"] = len(obj)
      if _req("is_one_series", return_metadata):
          metadata["is_one_series"] = len(obj) == 1
      if _req("n_panels", return_metadata):
          metadata["n_panels"] = 1
      if _req("is_one_panel", return_metadata):
          metadata["is_one_panel"] = True
      if _req("has_nans", return_metadata):
          metadata["has_nans"] = _nested_dataframe_has_nans(obj)
      if _req("is_equal_length", return_metadata):
          metadata[
              "is_equal_length"
          ] = not _nested_dataframe_has_unequal(obj)
      if _req("n_features", return_metadata):
          metadata["n_features"] = len(obj.columns)
      if _req("feature_names", return_metadata):
          metadata["feature_names"] = obj.columns.to_list()
  
      # todo: this is temporary override, proper is_empty logic needs to be added
      if _req("is_empty", return_metadata):
          metadata["is_empty"] = False
      if _req("is_equally_spaced", return_metadata):
          metadata["is_equally_spaced"] = True
      # end hacks
  
      return _ret(True, None, metadata, return_metadata)
  
file_path: sktime/sktime/datatypes/_panel/_check.py
imports: import numpy
  import pandas
  from pandas.core.dtypes.cast import is_nested_object
  from sktime.datatypes._common import _req, _ret
  from sktime.datatypes._series._check import _index_equally_spaced, check_pddataframe_series
  from sktime.utils.validation._dependencies import _check_soft_dependencies
  from sktime.utils.validation.series import is_in_valid_index_types, is_integer_index
label_desc: Use image node_id 9 for calling a global function with example usage: is_nested_dataframe(obj, return_metadata, var_name) and returns: _ret, _ret, _ret, _ret, _ret, _ret