Repository: scikit-learn/scikit-learn
File: sklearn/preprocessing/_target_encoder.py (Python)

Code before:
                shuffle=self.shuffle,
                random_state=self.random_state,
            )

        if _routing_enabled():
            if params["groups"] is not None:
                X, y, params["groups"] = indexable(X, y, params["groups"])
            routed_params = process_routing(self, "fit_transform", **params)
        else:
            routed_params = Bunch(splitter=Bunch(split={}))

        # The CV splitter is restricted to splitters where each sample index appears in
        # exactly one validation fold; otherwise the `fit_transform` output would be
        # ill-defined. We exclude a predefined list of all well defined splitters in
        # scikit-learn from the check:
        non_overlapping_splitters = (
            GroupKFold,
            KFold,
            StratifiedKFold,
            StratifiedGroupKFold,
        )
        if cv.__class__ not in non_overlapping_splitters:
            _test_indices = np.array([])
            for fold in cv.split(X, y, **routed_params.splitter.split):
                _, test_idx = fold
                _test_indices = np.concatenate([_test_indices, test_idx])
            if not np.isin(np.arange(X.shape[0]), _test_indices).all():
                raise ValueError(
                    "Validation indices from `cv` must cover each sample index exactly "
                    "once with no overlap. Pass a splitter with non-overlapping "
                    "validation folds as `cv` or refer to the docs for other options."
                )

        self.cv_ = cv.__class__.__name__

        # If 'multiclass' multiply axis=1 by num classes else keep shape the same
        if self.target_type_ == "multiclass":
            X_out = np.empty(
                (X_ordinal.shape[0], X_ordinal.shape[1] * len(self.classes_)),
                dtype=np.float64,
            )
        else:
            X_out = np.empty_like(X_ordinal, dtype=np.float64)

        for train_idx, test_idx in cv.split(X, y, **routed_params.splitter.split):
            X_train, y_train = X_ordinal[train_idx, :], y_encoded[train_idx]
            y_train_mean = np.mean(y_train, axis=0)

            if self.target_type_ == "multiclass":
                encodings = self._fit_encoding_multiclass(
                    X_train,

Review comment (suggestion):
using `np.concaetenate` allocates new arrays during each cycle. As an alternative can we create an int array of length `X.shape[0]`, add 1 to each position we seen, and then check that all the values are 1?

High level:

```python
seen_count= np.zeros(X.shape[0])
for _, test_idx in cv.split(...):
    seen_count[test_idx] += 1

# check that all seen_count is equal to one
```

Code after:
                seen_count[test_idx] += 1
            if not np.all(seen_count == 1):
                raise ValueError(
                    "Validation indices from `cv` must cover each sample index exactly "
                    "once with no overlap. Pass a splitter with non-overlapping "
                    "validation folds as `cv` or refer to the docs for other options."
                )

        # If 'multiclass' multiply axis=1 by num classes else keep shape the same
        if self.target_type_ == "multiclass":
            X_out = np.empty(
                (X_ordinal.shape[0], X_ordinal.shape[1] * len(self.classes_)),
                dtype=np.float64,
            )
        else:
            X_out = np.empty_like(X_ordinal, dtype=np.float64)

        for train_idx, test_idx in cv.split(X, y, **routed_params.splitter.split):
            X_train, y_train = X_ordinal[train_idx, :], y_encoded[train_idx]
            y_train_mean = np.mean(y_train, axis=0)

            if self.target_type_ == "multiclass":
                encodings = self._fit_encoding_multiclass(
                    X_train,
                    y_train,
                    n_categories,
                    y_train_mean,
                )
            else:
                encodings = self._fit_encoding_binary_or_continuous(
                    X_train,
                    y_train,
                    n_categories,
                    y_train_mean,
                )
            self._transform_X_ordinal(
                X_out,
                X_ordinal,
                ~X_known_mask,
                test_idx,
                encodings,
                y_train_mean,
            )
        return X_out

    def transform(self, X):
        """Transform X with the target encoding.

        This method internally uses the `encodings_` attribute learnt during
        :meth:`TargetEncoder.fit_transform` to transform test data.