def add(self, X, y, check_input=False):
        """Add new data X, y to the binning sketch of each variable.

        Parameters
        ----------
        X : pandas.DataFrame, shape (n_samples, n_features)

        y : array-like of shape (n_samples,)
            Target vector relative to x.

        check_input : bool (default=False)
            Whether to check input arrays.

        Returns
        -------
        self : BinningProcessSketch
            Binning process with new data.
        """
        if not self._is_started:
            self._n_samples = 0
            self._n_variables = len(self.variable_names)

            if self.categorical_variables is not None:
                self._n_categorical = len(self.categorical_variables)
            else:
                self._n_categorical = 0

            self._n_numerical = self._n_variables - self._n_categorical

            # Check selection criteria
            if self.selection_criteria is not None:
                _check_selection_criteria(self.selection_criteria,
                                          self._target_dtype)

            # Initialize bsketch for each variable. To avoid mixed dtypes
            # the user must provide a dtype for all variables. This differs
            # from the BinningProcess, where dtypes are inferred.
            for name in self.variable_names:
                if (self.categorical_variables is not None and
                        name in self.categorical_variables):
                    dtype = "categorical"
                else:
                    dtype = "numerical"

                optb = OptimalBinningSketch(
                        name=name, dtype=dtype,
                        max_n_prebins=self.max_n_prebins,
                        min_n_bins=self.min_n_bins,
                        max_n_bins=self.max_n_bins,
                        min_bin_size=self.min_bin_size,
                        max_pvalue=self.max_pvalue,
                        max_pvalue_policy=self.max_pvalue_policy,
                        special_codes=self.special_codes,
                        split_digits=self.split_digits)

                if self.binning_fit_params is not None:
                    params = self.binning_fit_params.get(name, {})
                else:
                    params = {}

                optb.set_params(**params)

                self._variable_dtypes[name] = dtype
                self._binned_variables[name] = optb

            self._is_started = True

        # Add new data stream
        time_add = time.perf_counter()

        # Add data to variables that appear in X. During training the
        # data columns might change, for example, not all data sources
        # contain the same variables.
        for name in X.columns:
            if name in self.variable_names:
                if self.verbose:
                    logger.info("Add variable: {}.".format(name))

                self._binned_variables[name].add(X[name], y, check_input)

        # Update count samples and addition operations
        self._n_samples += X.shape[0]
        self._n_add += 1

        self._time_streaming_add += time.perf_counter() - time_add

        if self.verbose:
            logger.info("Sketch: added new data.")

        return self
Add new data X, y to the binning sketch of each variable.

        Parameters
        ----------
        X : pandas.DataFrame, shape (n_samples, n_features)

        y : array-like of shape (n_samples,)
            Target vector relative to x.

        check_input : bool (default=False)
            Whether to check input arrays.

        Returns
        -------
        self : BinningProcessSketch
            Binning process with new data.
        
optbinning/binning/distributed/binning_process_sketch.py