# Buggy code
def fit(self, X, y):
    """
    Fit the NearestCentroid model according to the given training data.

    Parameters
    ----------
    X : {array-like, sparse matrix} of shape (n_samples, n_features)
        Training vector, where n_samples is the number of samples and
        n_features is the number of features.
        Note that centroid shrinking cannot be used with sparse matrices.
    y : array-like of shape (n_samples,)
        Target values (integers)
    """
    if self.metric == "precomputed":
        raise ValueError("Precomputed is not supported.")
    # If X is sparse and the metric is "manhattan", store it in a csc
    # format is easier to calculate the median.
    if self.metric == "manhattan":
        X, y = self._validate_data(X, y, accept_sparse=["csc"])
    else:
        X, y = self._validate_data(X, y, accept_sparse=["csr", "csc"])
    is_X_sparse = sp.issparse(X)
    if is_X_sparse and self.shrink_threshold:
        raise ValueError("threshold shrinking not supported for sparse input")
    check_classification_targets(y)

    n_samples, n_features = X.shape
    le = LabelEncoder()
    y_ind = le.fit_transform(y)
    self.classes_ = classes = le.classes_
    n_classes = classes.size
    if n_classes < 2:
        raise ValueError(
            "The number of classes has to be greater than"
            " one; got %d class" % (n_classes)
        )

    # Mask mapping each class to its members.
    self.centroids_ = np.empty((n_classes, n_features), dtype=np.float64)
    # Number of clusters in each class.
    nk = np.zeros(n_classes)

    for cur_class in range(n_classes):
        center_mask = y_ind == cur_class
        nk[cur_class] = np.sum(center_mask)
        if is_X_sparse:
            center_mask = np.where(center_mask)[0]

        # XXX: Update other averaging methods according to the metrics.
        if self.metric == "manhattan":
            # NumPy does not calculate median of sparse matrices.
            if not is_X_sparse:
                self.centroids_[cur_class] = np.median(X[center_mask], axis=0)
            else:
                self.centroids_[cur_class] = csc_median_axis_0(X[center_mask])
        else:
            if self.metric != "euclidean":
                warnings.warn(
                    "Averaging for metrics other than "
                    "euclidean and manhattan not supported. "
                    "The average is set to be the mean."
                )
            self.centroids_[cur_class] = X[center_mask].mean(axis=0)

    if self.shrink_threshold:
        dataset_centroid_ = np.mean(X, axis=0)

        # m parameter for determining deviation
        m = np.sqrt((1.0 / nk) - (1.0 / n_samples))
        # Calculate deviation using the standard deviation of centroids.
        variance = (X - self.centroids_[y_ind]) ** 2
        variance = variance.sum(axis=0)
        s = np.sqrt(variance / (n_samples - n_classes))
        s += np.median(s)  # To deter outliers from affecting the results.
        mm = m.reshape(len(m), 1)  # Reshape to allow broadcasting.
        ms = mm * s
        deviation = (self.centroids_ - dataset_centroid_) / ms
        # Soft thresholding: if the deviation crosses 0 during shrinking,
        # it becomes zero.
        signs = np.sign(deviation)
        deviation = np.abs(deviation) - self.shrink_threshold
        np.clip(deviation, 0, None, out=deviation)
        deviation *= signs
        # Now adjust the centroids using the deviation
        msd = ms * deviation
        self.centroids_ = dataset_centroid_[np.newaxis, :] + msd
    return self


# Traceback (ValueError)
C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\neighbors\nearest_centroid.py:159: RuntimeWarning: invalid value encountered in true_divide
deviation = ((self.centroids_ - dataset_centroid_) / ms)
C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\neighbors\nearest_centroid.py:162: RuntimeWarning: invalid value encountered in sign
signs = np.sign(deviation)
Traceback (most recent call last):
File "C:/Users/sherbold/PycharmProjects/icb/tmp.py", line 21, in <module>
clf.predict(X)
File "C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\neighbors\nearest_centroid.py", line 194, in predict
X, self.centroids_, metric=self.metric).argmin(axis=1)]
File "C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\metrics\pairwise.py", line 1588, in pairwise_distances
return _parallel_pairwise(X, Y, func, n_jobs, **kwds)
File "C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\metrics\pairwise.py", line 1206, in _parallel_pairwise
return func(X, Y, **kwds)
File "C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\metrics\pairwise.py", line 232, in euclidean_distances
X, Y = check_pairwise_arrays(X, Y)
File "C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\metrics\pairwise.py", line 114, in check_pairwise_arrays
estimator=estimator)
File "C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\utils\validation.py", line 542, in check_array
allow_nan=force_all_finite == 'allow-nan')
File "C:\Users\sherbold\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\utils\validation.py", line 56, in _assert_all_finite
raise ValueError(msg_err.format(type_err, X.dtype))
ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

# Fixed code
def fit(self, X, y):
    """
    Fit the NearestCentroid model according to the given training data.

    Parameters
    ----------
    X : {array-like, sparse matrix} of shape (n_samples, n_features)
        Training vector, where n_samples is the number of samples and
        n_features is the number of features.
        Note that centroid shrinking cannot be used with sparse matrices.
    y : array-like of shape (n_samples,)
        Target values (integers)
    """
    if self.metric == "precomputed":
        raise ValueError("Precomputed is not supported.")
    # If X is sparse and the metric is "manhattan", store it in a csc
    # format is easier to calculate the median.
    if self.metric == "manhattan":
        X, y = self._validate_data(X, y, accept_sparse=["csc"])
    else:
        X, y = self._validate_data(X, y, accept_sparse=["csr", "csc"])
    is_X_sparse = sp.issparse(X)
    if is_X_sparse and self.shrink_threshold:
        raise ValueError("threshold shrinking not supported for sparse input")
    check_classification_targets(y)

    n_samples, n_features = X.shape
    le = LabelEncoder()
    y_ind = le.fit_transform(y)
    self.classes_ = classes = le.classes_
    n_classes = classes.size
    if n_classes < 2:
        raise ValueError(
            "The number of classes has to be greater than"
            " one; got %d class" % (n_classes)
        )

    # Mask mapping each class to its members.
    self.centroids_ = np.empty((n_classes, n_features), dtype=np.float64)
    # Number of clusters in each class.
    nk = np.zeros(n_classes)

    for cur_class in range(n_classes):
        center_mask = y_ind == cur_class
        nk[cur_class] = np.sum(center_mask)
        if is_X_sparse:
            center_mask = np.where(center_mask)[0]

        # XXX: Update other averaging methods according to the metrics.
        if self.metric == "manhattan":
            # NumPy does not calculate median of sparse matrices.
            if not is_X_sparse:
                self.centroids_[cur_class] = np.median(X[center_mask], axis=0)
            else:
                self.centroids_[cur_class] = csc_median_axis_0(X[center_mask])
        else:
            if self.metric != "euclidean":
                warnings.warn(
                    "Averaging for metrics other than "
                    "euclidean and manhattan not supported. "
                    "The average is set to be the mean."
                )
            self.centroids_[cur_class] = X[center_mask].mean(axis=0)

    if self.shrink_threshold:
        if np.all(np.ptp(X, axis=0) == 0):
            raise ValueError("All features have zero variance. Division by zero.")
        dataset_centroid_ = np.mean(X, axis=0)

        # m parameter for determining deviation
        m = np.sqrt((1.0 / nk) - (1.0 / n_samples))
        # Calculate deviation using the standard deviation of centroids.
        variance = (X - self.centroids_[y_ind]) ** 2
        variance = variance.sum(axis=0)
        s = np.sqrt(variance / (n_samples - n_classes))
        s += np.median(s)  # To deter outliers from affecting the results.
        mm = m.reshape(len(m), 1)  # Reshape to allow broadcasting.
        ms = mm * s
        deviation = (self.centroids_ - dataset_centroid_) / ms
        # Soft thresholding: if the deviation crosses 0 during shrinking,
        # it becomes zero.
        signs = np.sign(deviation)
        deviation = np.abs(deviation) - self.shrink_threshold
        np.clip(deviation, 0, None, out=deviation)
        deviation *= signs
        # Now adjust the centroids using the deviation
        msd = ms * deviation
        self.centroids_ = dataset_centroid_[np.newaxis, :] + msd
    return self