code: def quantile_biner(
      df: pd.DataFrame,
      columns_to_bin: List[str],
      q: int = 4,
      right: bool = False,
  ) -> LearnerReturnType:
      """
      Discretize continuous numerical columns into its quantiles. Uses pandas.qcut
      to find the bins and then numpy.digitize to fit the columns into bins.
  
      The default behaviour is to replace the original values. To store
      the original values in a new column, specify `prefix` or `suffix`
      in the parameters, or specify a dictionary with the desired column
      mapping using the `columns_mapping` parameter.
  
      Parameters
      ----------
      df : pandas.DataFrame
          A Pandas' DataFrame that must contain `columns_to_categorize` columns.
  
      columns_to_bin : list of str
          A list of numerical column names.
  
      q : int
          Number of quantiles. 10 for deciles, 4 for quartiles, etc.
          Alternately array of quantiles, e.g. [0, .25, .5, .75, 1.] for quartiles.
          See https://pandas.pydata.org/pandas-docs/stable/generated/pandas.qcut.html
  
      right : bool
          Indicating whether the intervals include the right or the left bin edge.
          Default behavior is (right==False) indicating that the interval does not
          include the right edge. The left bin end is open in this case, i.e., bins[i-1]
          <= x < bins[i] is the default behavior for monotonically increasing bins.
          See https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.digitize.html
      """
  
      bin_getter = lambda col: pd.qcut(df[col], q, retbins=True)[1]
      bins = {column: bin_getter(column) for column in columns_to_bin}
  
      def p(new_df: pd.DataFrame) -> pd.DataFrame:
          col_biner = lambda col: np.where(
              new_df[col].isnull(),
              nan,
              np.digitize(new_df[col], bins[col], right=right),
          )
          bined_columns = {
              col: col_biner(col) for col in columns_to_bin
          }
          return new_df.assign(**bined_columns)
  
      p.__doc__ = learner_pred_fn_docstring("quantile_biner")
  
      log = {
          "quantile_biner": {
              "transformed_column": columns_to_bin,
              "q": q,
          }
      }
  
      return p, p(df), 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 13 for calling a global function with example usage: quantile_biner(df, columns_to_bin, q, right) and returns: p,  p,  log, new_df