code: def null_injector(
      df: pd.DataFrame,
      proportion: float,
      columns_to_inject: Optional[List[str]] = None,
      groups: Optional[List[List[str]]] = None,
      seed: int = 1,
  ) -> LearnerReturnType:
      """
      Injects null into columns
  
      Parameters
      ----------
      df : pandas.DataFrame
          A Pandas' DataFrame that must contain `columns_to_inject` as columns
  
      columns_to_inject : list of str
          A list of features to inject nulls. If groups is not None it will be ignored.
  
      proportion : float
          Proportion of nulls to inject in the columns.
  
      groups : list of list of str (default = None)
          A list of group of features. If not None, feature in the same group will be set to NaN together.
  
      seed : int
          Random seed for consistency.
      """
      if proportion < 0 or proportion > 1:
          raise ValueError("proportions must be between 0 and 1.")
      if not ((columns_to_inject is None) ^ (groups is None)):
          raise ValueError(
              "Either columns_to_inject or groups must be None."
          )
  
      n_rows = df.shape[0]
  
      groups = (
          [[f] for f in columns_to_inject]
          if columns_to_inject is not None
          else groups
      )
  
      null_cols = {}  # type: ignore
      for seed_i, group in enumerate(groups):  # type: ignore
          np.random.seed(seed + seed_i)
          replace_mask = np.random.binomial(
              1, 1 - proportion, n_rows
          ).astype(bool)
          null_cols = merge(
              null_cols,
              {
                  feature: df[feature].where(replace_mask)
                  for feature in group
              },
          )
  
      null_data = df.assign(**null_cols)
  
      def p(new_data_set: pd.DataFrame) -> pd.DataFrame:
          return new_data_set
  
      p.__doc__ = learner_pred_fn_docstring("null_injector")
  
      log = {
          "null_injector": {
              "columns_to_inject": columns_to_inject,
              "proportion": proportion,
              "groups": groups,
          }
      }
  
      return p, null_data, log
  
imports: from typing import Any, Callable, Dict, List, Union, Optional
  import numpy
  import pandas
  from numpy import nan
  from sklearn.preprocessing import StandardScaler
  from statsmodels.distributions import empirical_distribution
  from toolz import curry, merge, compose, mapcat
  from fklearn.common_docstrings import learner_return_docstring, learner_pred_fn_docstring
  from fklearn.training.utils import log_learner_time
  from fklearn.types import LearnerReturnType, LearnerLogType
  from fklearn.preprocessing.schema import column_duplicatable
label_desc: Use image node_id 18 for calling a global function with example usage: null_injector(df, proportion, columns_to_inject, groups, seed) and returns: p,  null_data,  log, new_data_set