code: def test_pandas_categorical(self, data_split_mode=DataSplitMode.ROW):
      world_size = xgb.collective.get_world_size()
      rng = np.random.RandomState(1994)
      rows = 100
      X = rng.randint(3, 7, size=rows)
      X = pd.Series(X, dtype="category")
      X = pd.DataFrame({"f0": X})
      y = rng.randn(rows)
      m = xgb.DMatrix(
          X, y, enable_categorical=True, data_split_mode=data_split_mode
      )
      assert m.feature_types[0] == "c"
  
      X_0 = ["f", "o", "o"]
      X_1 = [4, 3, 2]
      X = pd.DataFrame({"feat_0": X_0, "feat_1": X_1})
      X["feat_0"] = X["feat_0"].astype("category")
      transformed, _, feature_types = xgb.data._transform_pandas_df(
          X, enable_categorical=True
      )
  
      assert transformed.columns[0].min() == 0
  
      # test missing value
      X = pd.DataFrame({"f0": ["a", "b", np.NaN]})
      X["f0"] = X["f0"].astype("category")
      arr, _, _ = xgb.data._transform_pandas_df(
          X, enable_categorical=True
      )
      for c in arr.columns:
          assert not np.any(c == -1.0)
  
      X = X["f0"]
      y = y[: X.shape[0]]
      with pytest.raises(ValueError, match=r".*enable_categorical.*"):
          xgb.DMatrix(X, y, data_split_mode=data_split_mode)
  
      Xy = xgb.DMatrix(
          X, y, enable_categorical=True, data_split_mode=data_split_mode
      )
      assert Xy.num_row() == 3
      if data_split_mode == DataSplitMode.ROW:
          assert Xy.num_col() == 1
      else:
          assert Xy.num_col() == 1 * world_size
  
imports: from typing import Type
  import numpy
  import pytest
  import xgboost
  from xgboost import testing
  from xgboost.core import DataSplitMode
  from xgboost.testing.data import pd_arrow_dtypes, pd_dtypes, run_base_margin_info
label_desc: Use image node_id 4 for calling the TestPandas obj's underlying member method code with example usage: obj.test_pandas_categorical(data_split_mode) without return types