class_docstr: Class defining categorical distribution type functionality
docstr: Expands the feature dimension for each categorical column by:
  - One hot encode each of the categorical features
  - For each feature, get handle on groups of one-hot expanded columns
  - Store the handle groups
  - Return expanded array
  NOTE: the number of expanded columns is EQUAL to the number of classes
  for ease of use with the Pytorch loss functions.
  This is technically wasteful computationally (only need C-1 columns).
  
  Args:
      X: The original passed-in data.
  
      fit_transform: Whether the class first fits
      then transforms the data, or just transforms.
      Just transforming is used to preprocess new data after the
      initial NOTEARS fit.
  
  Returns:
      Preprocessed X
docstr_tok: ["Expands","the","feature","dimension","for","each","categorical","column","by",":","-","One","hot","encode","each","of","the","categorical","features","-","For","each","feature",",","get","handle","on","groups","of","one-hot","expanded","columns","-","Store","the","handle","groups","-","Return","expanded","array","NOTE",":","the","number","of","expanded","columns","is","EQUAL","to","the","number","of","classes","for","ease","of","use","with","the","Pytorch","loss","functions",".","This","is","technically","wasteful","computationally","(","only","need","C-1","columns",")",".","Args",":","X",":","The","original","passed-in","data",".","fit_transform",":","Whether","the","class","first","fits","then","transforms","the","data",",","or","just","transforms",".","Just","transforming","is","used","to","preprocess","new","data","after","the","initial","NOTEARS","fit",".","Returns",":","Preprocessed","X"]
code: def preprocess_X(
      self, X: np.ndarray, fit_transform: bool = True
  ) -> np.ndarray:
      """
      Expands the feature dimension for each categorical column by:
      - One hot encode each of the categorical features
      - For each feature, get handle on groups of one-hot expanded columns
      - Store the handle groups
      - Return expanded array
      NOTE: the number of expanded columns is EQUAL to the number of classes
      for ease of use with the Pytorch loss functions.
      This is technically wasteful computationally (only need C-1 columns).
  
      Args:
          X: The original passed-in data.
  
          fit_transform: Whether the class first fits
          then transforms the data, or just transforms.
          Just transforming is used to preprocess new data after the
          initial NOTEARS fit.
  
      Returns:
          Preprocessed X
      """
      # deepcopy to prevent overwrite errors
      X = deepcopy(X)
  
      # fit the OneHotEncoder
      if fit_transform:
          self.encoder = OneHotEncoder(
              sparse=False, categories="auto", drop=None
          )
          self.encoder.fit(X[:, [self.idx]])
  
      # expand columns for this feature
      expanded_columns = self.encoder.transform(X[:, [self.idx]])
      # update the original column with the first expanded column
      X[:, self.idx] = expanded_columns[:, 0]
      # append the remainder cols to X
      X = self._expand_columns(X, expanded_columns[:, 1:])
  
      # update the idx_group with expanded columns
      if fit_transform:
          self.idx_group = []
          # preserve the first column location
          self.idx_group.append(self.idx)
          # the new cols are appended to the end of X contiguously
          n_new_cols = expanded_columns.shape[1] - 1
          idx_start = X.shape[1] - n_new_cols
          # preserve location of expanded columns
          self.idx_group += list(range(idx_start, X.shape[1]))
  
      return X
  
imports: from copy import deepcopy
  from typing import Dict, List, Tuple
  import numpy
  import torch
  from sklearn.preprocessing import OneHotEncoder
  from torch import nn
  from causalnex.structure.pytorch.dist_type._base import DistTypeBase, ExpandColumnsMixin
  from causalnex.structure.structuremodel import StructureModel
label_desc: Use image node_id 2 for calling the DistTypeCategorical obj's underlying member method code with example usage: obj.preprocess_X(X, fit_transform) and returns: X