class_docstr: Bin continuous data into intervals.
  
  Read more in the :ref:`User Guide <preprocessing_discretization>`.
  
  .. versionadded:: 0.20
  
  Parameters
  ----------
  n_bins : int or array-like of shape (n_features,), default=5
      The number of bins to produce. Raises ValueError if ``n_bins < 2``.
  
  encode : {'onehot', 'onehot-dense', 'ordinal'}, default='onehot'
      Method used to encode the transformed result.
  
      - 'onehot': Encode the transformed result with one-hot encoding
        and return a sparse matrix. Ignored features are always
        stacked to the right.
      - 'onehot-dense': Encode the transformed result with one-hot encoding
        and return a dense array. Ignored features are always
        stacked to the right.
      - 'ordinal': Return the bin identifier encoded as an integer value.
  
  strategy : {'uniform', 'quantile', 'kmeans'}, default='quantile'
      Strategy used to define the widths of the bins.
  
      - 'uniform': All bins in each feature have identical widths.
      - 'quantile': All bins in each feature have the same number of points.
      - 'kmeans': Values in each bin have the same nearest center of a 1D
        k-means cluster.
  
      For an example of the different strategies see:
      :ref:`sphx_glr_auto_examples_preprocessing_plot_discretization_strategies.py`.
  
  dtype : {np.float32, np.float64}, default=None
      The desired data-type for the output. If None, output dtype is
      consistent with input dtype. Only np.float32 and np.float64 are
      supported.
  
      .. versionadded:: 0.24
  
  subsample : int or None, default='warn'
      Maximum number of samples, used to fit the model, for computational
      efficiency. Defaults to 200_000 when `strategy='quantile'` and to `None`
      when `strategy='uniform'` or `strategy='kmeans'`.
      `subsample=None` means that all the training samples are used when
      computing the quantiles that determine the binning thresholds.
      Since quantile computation relies on sorting each column of `X` and
      that sorting has an `n log(n)` time complexity,
      it is recommended to use subsampling on datasets with a
      very large number of samples.
  
      .. versionchanged:: 1.3
          The default value of `subsample` changed from `None` to `200_000` when
          `strategy="quantile"`.
  
      .. versionchanged:: 1.5
          The default value of `subsample` changed from `None` to `200_000` when
          `strategy="uniform"` or `strategy="kmeans"`.
  
  random_state : int, RandomState instance or None, default=None
      Determines random number generation for subsampling.
      Pass an int for reproducible results across multiple function calls.
      See the `subsample` parameter for more details.
      See :term:`Glossary <random_state>`.
  
      .. versionadded:: 1.1
  
  Attributes
  ----------
  bin_edges_ : ndarray of ndarray of shape (n_features,)
      The edges of each bin. Contain arrays of varying shapes ``(n_bins_, )``
      Ignored features will have empty arrays.
  
  n_bins_ : ndarray of shape (n_features,), dtype=np.int64
      Number of bins per feature. Bins whose width are too small
      (i.e., <= 1e-8) are removed with a warning.
  
  n_features_in_ : int
      Number of features seen during :term:`fit`.
  
      .. versionadded:: 0.24
  
  feature_names_in_ : ndarray of shape (`n_features_in_`,)
      Names of features seen during :term:`fit`. Defined only when `X`
      has feature names that are all strings.
  
      .. versionadded:: 1.0
  
  See Also
  --------
  Binarizer : Class used to bin values as ``0`` or
      ``1`` based on a parameter ``threshold``.
  
  Notes
  -----
  
  For a visualization of discretization on different datasets refer to
  :ref:`sphx_glr_auto_examples_preprocessing_plot_discretization_classification.py`.
  On the effect of discretization on linear models see:
  :ref:`sphx_glr_auto_examples_preprocessing_plot_discretization.py`.
  
  In bin edges for feature ``i``, the first and last values are used only for
  ``inverse_transform``. During transform, bin edges are extended to::
  
    np.concatenate([-np.inf, bin_edges_[i][1:-1], np.inf])
  
  You can combine ``KBinsDiscretizer`` with
  :class:`~sklearn.compose.ColumnTransformer` if you only want to preprocess
  part of the features.
  
  ``KBinsDiscretizer`` might produce constant features (e.g., when
  ``encode = 'onehot'`` and certain bins do not contain any data).
  These features can be removed with feature selection algorithms
  (e.g., :class:`~sklearn.feature_selection.VarianceThreshold`).
  
  Examples
  --------
  >>> from sklearn.preprocessing import KBinsDiscretizer
  >>> X = [[-2, 1, -4,   -1],
  ...      [-1, 2, -3, -0.5],
  ...      [ 0, 3, -2,  0.5],
  ...      [ 1, 4, -1,    2]]
  >>> est = KBinsDiscretizer(
  ...     n_bins=3, encode='ordinal', strategy='uniform', subsample=None
  ... )
  >>> est.fit(X)
  KBinsDiscretizer(...)
  >>> Xt = est.transform(X)
  >>> Xt  # doctest: +SKIP
  array([[ 0., 0., 0., 0.],
         [ 1., 1., 1., 0.],
         [ 2., 2., 2., 1.],
         [ 2., 2., 2., 2.]])
  
  Sometimes it may be useful to convert the data back into the original
  feature space. The ``inverse_transform`` function converts the binned
  data into the original feature space. Each value will be equal to the mean
  of the two bin edges.
  
  >>> est.bin_edges_[0]
  array([-2., -1.,  0.,  1.])
  >>> est.inverse_transform(Xt)
  array([[-1.5,  1.5, -3.5, -0.5],
         [-0.5,  2.5, -2.5, -0.5],
         [ 0.5,  3.5, -1.5,  0.5],
         [ 0.5,  3.5, -1.5,  1.5]])
class_docstr_tok: ["Bin","continuous","data","into","intervals",".","Read","more","in","the",":","ref",":","`","User","Guide","<","preprocessing_discretization",">","`",".","..","versionadded",":",":","0.20","Parameters","--","--","--","--","--","n_bins",":","int","or","array-like","of","shape","(","n_features",",",")",",","default=5","The","number","of","bins","to","produce",".","Raises","ValueError","if","``","n_bins","<","2","``",".","encode",":","{","'onehot","'",",","'onehot-dense","'",",","'ordinal","'","}",",","default='onehot'","Method","used","to","encode","the","transformed","result",".","-","'onehot","'",":","Encode","the","transformed","result","with","one-hot","encoding","and","return","a","sparse","matrix",".","Ignored","features","are","always","stacked","to","the","right",".","-","'onehot-dense","'",":","Encode","the","transformed","result","with","one-hot","encoding","and","return","a","dense","array",".","Ignored","features","are","always","stacked","to","the","right",".","-","'ordinal","'",":","Return","the","bin","identifier","encoded","as","an","integer","value",".","strategy",":","{","'uniform","'",",","'quantile","'",",","'kmeans","'","}",",","default='quantile'","Strategy","used","to","define","the","widths","of","the","bins",".","-","'uniform","'",":","All","bins","in","each","feature","have","identical","widths",".","-","'quantile","'",":","All","bins","in","each","feature","have","the","same","number","of","points",".","-","'kmeans","'",":","Values","in","each","bin","have","the","same","nearest","center","of","a","1D","k-means","cluster",".","For","an","example","of","the","different","strategies","see",":",":","ref",":","`","sphx_glr_auto_examples_preprocessing_plot_discretization_strategies.py","`",".","dtype",":","{","np.float32",",","np.float64","}",",","default=None","The","desired","data-type","for","the","output",".","If","None",",","output","dtype","is","consistent","with","input","dtype",".","Only","np.float32","and","np.float64","are","supported",".","..","versionadded",":",":","0.24","subsample",":","int","or","None",",","default='warn'","Maximum","number","of","samples",",","used","to","fit","the","model",",","for","computational","efficiency",".","Defaults","to","200_000","when","`","strategy='quantile","'","`","and","to","`","None","`","when","`","strategy='uniform","'","`","or","`","strategy='kmeans","'","`",".","`","subsample=None","`","means","that","all","the","training","samples","are","used","when","computing","the","quantiles","that","determine","the","binning","thresholds",".","Since","quantile","computation","relies","on","sorting","each","column","of","`","X","`","and","that","sorting","has","an","`","n","log","(","n",")","`","time","complexity",",","it","is","recommended","to","use","subsampling","on","datasets","with","a","very","large","number","of","samples",".","..","versionchanged",":",":","1.3","The","default","value","of","`","subsample","`","changed","from","`","None","`","to","`","200_000","`","when","`","strategy=","''","quantile","''","`",".","..","versionchanged",":",":","1.5","The","default","value","of","`","subsample","`","changed","from","`","None","`","to","`","200_000","`","when","`","strategy=","''","uniform","''","`","or","`","strategy=","''","kmeans","''","`",".","random_state",":","int",",","RandomState","instance","or","None",",","default=None","Determines","random","number","generation","for","subsampling",".","Pass","an","int","for","reproducible","results","across","multiple","function","calls",".","See","the","`","subsample","`","parameter","for","more","details",".","See",":","term",":","`","Glossary","<","random_state",">","`",".","..","versionadded",":",":","1.1","Attributes","--","--","--","--","--","bin_edges_",":","ndarray","of","ndarray","of","shape","(","n_features",",",")","The","edges","of","each","bin",".","Contain","arrays","of","varying","shapes","``","(","n_bins_",",",")","``","Ignored","features","will","have","empty","arrays",".","n_bins_",":","ndarray","of","shape","(","n_features",",",")",",","dtype=np.int64","Number","of","bins","per","feature",".","Bins","whose","width","are","too","small","(","i.e.",",","<","=","1e-8",")","are","removed","with","a","warning",".","n_features_in_",":","int","Number","of","features","seen","during",":","term",":","`","fit","`",".","..","versionadded",":",":","0.24","feature_names_in_",":","ndarray","of","shape","(","`","n_features_in_","`",",",")","Names","of","features","seen","during",":","term",":","`","fit","`",".","Defined","only","when","`","X","`","has","feature","names","that","are","all","strings",".","..","versionadded",":",":","1.0","See","Also","--","--","--","--","Binarizer",":","Class","used","to","bin","values","as","``","0","``","or","``","1","``","based","on","a","parameter","``","threshold","``",".","Notes","--","--","-","For","a","visualization","of","discretization","on","different","datasets","refer","to",":","ref",":","`","sphx_glr_auto_examples_preprocessing_plot_discretization_classification.py","`",".","On","the","effect","of","discretization","on","linear","models","see",":",":","ref",":","`","sphx_glr_auto_examples_preprocessing_plot_discretization.py","`",".","In","bin","edges","for","feature","``","i","``",",","the","first","and","last","values","are","used","only","for","``","inverse_transform","``",".","During","transform",",","bin","edges","are","extended","to",":",":","np.concatenate","(","[","-np.inf",",","bin_edges_","[","i","]","[","1",":","-1","]",",","np.inf","]",")","You","can","combine","``","KBinsDiscretizer","``","with",":","class",":","`","~sklearn.compose.ColumnTransformer","`","if","you","only","want","to","preprocess","part","of","the","features",".","``","KBinsDiscretizer","``","might","produce","constant","features","(","e.g.",",","when","``","encode","=","'onehot","'","``","and","certain","bins","do","not","contain","any","data",")",".","These","features","can","be","removed","with","feature","selection","algorithms","(","e.g.",",",":","class",":","`","~sklearn.feature_selection.VarianceThreshold","`",")",".","Examples","--","--","--","--",">",">",">","from","sklearn.preprocessing","import","KBinsDiscretizer",">",">",">","X","=","[","[","-2",",","1",",","-4",",","-1","]",",","...","[","-1",",","2",",","-3",",","-0.5","]",",","...","[","0",",","3",",","-2",",","0.5","]",",","...","[","1",",","4",",","-1",",","2","]","]",">",">",">","est","=","KBinsDiscretizer","(","...","n_bins=3",",","encode='ordinal","'",",","strategy='uniform","'",",","subsample=None","...",")",">",">",">","est.fit","(","X",")","KBinsDiscretizer","(","...",")",">",">",">","Xt","=","est.transform","(","X",")",">",">",">","Xt","#","doctest",":","+SKIP","array","(","[","[","0.",",","0.",",","0.",",","0",".","]",",","[","1.",",","1.",",","1.",",","0",".","]",",","[","2.",",","2.",",","2.",",","1",".","]",",","[","2.",",","2.",",","2.",",","2",".","]","]",")","Sometimes","it","may","be","useful","to","convert","the","data","back","into","the","original","feature","space",".","The","``","inverse_transform","``","function","converts","the","binned","data","into","the","original","feature","space",".","Each","value","will","be","equal","to","the","mean","of","the","two","bin","edges",".",">",">",">","est.bin_edges_","[","0","]","array","(","[","-2.",",","-1.",",","0.",",","1",".","]",")",">",">",">","est.inverse_transform","(","Xt",")","array","(","[","[","-1.5",",","1.5",",","-3.5",",","-0.5","]",",","[","-0.5",",","2.5",",","-2.5",",","-0.5","]",",","[","0.5",",","3.5",",","-1.5",",","0.5","]",",","[","0.5",",","3.5",",","-1.5",",","1.5","]","]",")"]
docstr: Returns n_bins_, the number of bins per feature.
docstr_tok: ["Returns","n_bins_",",","the","number","of","bins","per","feature","."]
code: def _validate_n_bins(self, n_features):
      """Returns n_bins_, the number of bins per feature."""
      orig_bins = self.n_bins
      if isinstance(orig_bins, Integral):
          return np.full(n_features, orig_bins, dtype=int)
  
      n_bins = check_array(
          orig_bins, dtype=int, copy=True, ensure_2d=False
      )
  
      if n_bins.ndim > 1 or n_bins.shape[0] != n_features:
          raise ValueError(
              "n_bins must be a scalar or array of shape (n_features,)."
          )
  
      bad_nbins_value = (n_bins < 2) | (n_bins != orig_bins)
  
      violating_indices = np.where(bad_nbins_value)[0]
      if violating_indices.shape[0] > 0:
          indices = ", ".join(str(i) for i in violating_indices)
          raise ValueError(
              "{} received an invalid number "
              "of bins at indices {}. Number of bins "
              "must be at least 2, and must be an int.".format(
                  KBinsDiscretizer.__name__, indices
              )
          )
      return n_bins
  
file_path: scikit-learn/sklearn/preprocessing/_discretization.py
imports: import warnings
  from numbers import Integral
  import numpy
  from ..base import BaseEstimator, TransformerMixin, _fit_context
  from ..utils import _safe_indexing
  from ..utils._param_validation import Hidden, Interval, Options, StrOptions
  from ..utils.stats import _weighted_percentile
  from ..utils.validation import _check_feature_names_in, _check_sample_weight, check_array, check_is_fitted, check_random_state
  from ._encoders import OneHotEncoder
label_desc: Use image node_id 3 for calling the KBinsDiscretizer obj's underlying member method code with example usage: obj._validate_n_bins(n_features) and returns: n_bins, np