





'''simple docstring'''


import warnings

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.metrics import pairwise_distances

warnings.filterwarnings('''ignore''')

lowerCAmelCase      :  Union[str, Any]      							='''K-MEANS-CLUST/ '''
def 							UpperCAmelCase_						(		__lowerCamelCase      :      str			,__lowerCamelCase      :      List[Any]			,__lowerCamelCase      :      Tuple=None				):
   if seed is not None:  # useful for obtaining consistent results
      np.random.seed(__lowerCamelCase				)
   lowercase_    :Union[str, Any]					    =				data.shape[0]  # number of data points

   # Pick K indices from range [0, N).
   lowercase_    :List[Any]					    =				np.random.randint(0			,__lowerCamelCase			,__lowerCamelCase				)

   # Keep centroids as dense format, as many entries will be nonzero due to averaging.
   # As long as at least one document in a cluster contains a word,
   # it will carry a nonzero weight in the TF-IDF vector of the centroid.
   lowercase_    :List[Any]					    =				data[rand_indices, :]

   return centroids
def 							UpperCAmelCase_						(		__lowerCamelCase      :      str			,__lowerCamelCase      :      Union[str, Any]				):
   return pairwise_distances(__lowerCamelCase			,__lowerCamelCase			,metric="euclidean"				)
def 							UpperCAmelCase_						(		__lowerCamelCase      :      List[Any]			,__lowerCamelCase      :      Optional[Any]				):
   # Compute distances between each data point and the set of centroids:
   # Fill in the blank (RHS only)
   lowercase_    :int					    =				centroid_pairwise_dist(__lowerCamelCase			,__lowerCamelCase				)

   # Compute cluster assignments for each data point:
   # Fill in the blank (RHS only)
   lowercase_    :int					    =				np.argmin(__lowerCamelCase			,axis=1				)

   return cluster_assignment
def 							UpperCAmelCase_						(		__lowerCamelCase      :      str			,__lowerCamelCase      :      List[str]			,__lowerCamelCase      :      Dict				):
   lowercase_    :Dict					    =				[]
   for i in range(__lowerCamelCase				):
      # Select all data points that belong to cluster i. Fill in the blank (RHS only)
      lowercase_    :Any					    =				data[cluster_assignment == i]
      # Compute the mean of the data points. Fill in the blank (RHS only)
      lowercase_    :List[str]					    =				member_data_points.mean(axis=0				)
      new_centroids.append(__lowerCamelCase				)
   lowercase_    :Union[str, Any]					    =				np.array(__lowerCamelCase				)

   return new_centroids
def 							UpperCAmelCase_						(		__lowerCamelCase      :      Any			,__lowerCamelCase      :      int			,__lowerCamelCase      :      Union[str, Any]			,__lowerCamelCase      :      List[str]				):
   lowercase_    :Any					    =				0.0
   for i in range(__lowerCamelCase				):
      # Select all data points that belong to cluster i. Fill in the blank (RHS only)
      lowercase_    :Union[str, Any]					    =				data[cluster_assignment == i, :]

      if member_data_points.shape[0] > 0:  # check if i-th cluster is non-empty
         # Compute distances from centroid to data points (RHS only)
         lowercase_    :List[Any]					    =				pairwise_distances(
             __lowerCamelCase			,[centroids[i]]			,metric="euclidean"				)
         lowercase_    :List[Any]					    =				distances**2
         heterogeneity += np.sum(__lowerCamelCase				)

   return heterogeneity
def 							UpperCAmelCase_						(		__lowerCamelCase      :      Tuple			,__lowerCamelCase      :      List[str]				):
   plt.figure(figsize=(7, 4)				)
   plt.plot(__lowerCamelCase			,linewidth=4				)
   plt.xlabel("# Iterations"				)
   plt.ylabel("Heterogeneity"				)
   plt.title(F'Heterogeneity of clustering over time, K={k:d}'				)
   plt.rcParams.update({"font.size": 16}				)
   plt.show()
def 							UpperCAmelCase_						(		__lowerCamelCase      :      Tuple			,__lowerCamelCase      :      List[Any]			,__lowerCamelCase      :      List[Any]			,__lowerCamelCase      :      Optional[Any]=5_00			,__lowerCamelCase      :      int=None			,__lowerCamelCase      :      Optional[int]=False				):
   lowercase_    :Tuple					    =				initial_centroids[:]
   lowercase_    :Optional[Any]					    =				None

   for itr in range(__lowerCamelCase				):
      if verbose:
         print(__lowerCamelCase			,end=""				)

      # 1. Make cluster assignments using nearest centroids
      lowercase_    :Dict					    =				assign_clusters(__lowerCamelCase			,__lowerCamelCase				)

      # 2. Compute a new centroid for each of the k clusters, averaging all data
      #    points assigned to that cluster.
      lowercase_    :Optional[int]					    =				revise_centroids(__lowerCamelCase			,__lowerCamelCase			,__lowerCamelCase				)

      # Check for convergence: if none of the assignments changed, stop
      if (
          prev_cluster_assignment is not None
          and (prev_cluster_assignment == cluster_assignment).all()
      ):
         break

      # Print number of new assignments
      if prev_cluster_assignment is not None:
         lowercase_    :Optional[int]					    =				np.sum(prev_cluster_assignment != cluster_assignment				)
         if verbose:
            print(
                F'    {num_changed:5d} elements changed their cluster assignment.'				)

        # Record heterogeneity convergence metric
      if record_heterogeneity is not None:
         # YOUR CODE HERE
         lowercase_    :List[Any]					    =				compute_heterogeneity(__lowerCamelCase			,__lowerCamelCase			,__lowerCamelCase			,__lowerCamelCase				)
         record_heterogeneity.append(__lowerCamelCase				)

      lowercase_    :Optional[Any]					    =				cluster_assignment[:]

   return centroids, cluster_assignment


# Mock test below
if False:  # change to true to run this test case.
       from sklearn import datasets as ds

       lowerCAmelCase      :  List[Any]      							=ds.load_iris()
       lowerCAmelCase      :  Any      							=3
       lowerCAmelCase      :  Dict      							=[]
       lowerCAmelCase      :  Union[str, Any]      							=get_initial_centroids(dataset['''data'''], k, seed=0)
       lowerCAmelCase      :  Optional[Any]      							=kmeans(
           dataset['''data'''],
           k,
           initial_centroids,
           maxiter=400,
           record_heterogeneity=heterogeneity,
           verbose=True,
       )
       plot_heterogeneity(heterogeneity, k)
def 							UpperCAmelCase_						(		__lowerCamelCase      :      pd.DataFrame			,__lowerCamelCase      :      np.ndarray			,__lowerCamelCase      :      Union[str, Any]=None				):
   # Fill missing values with given rules
   if fill_missing_report:
      lowercase_    :Optional[int]					    =				df.fillna(value=__lowerCamelCase				)
   lowercase_    :Any					    =				1
   lowercase_    :Optional[Any]					    =				df.select_dtypes(np.number				).columns
   lowercase_    :int					    =				(
       df.groupby(["Cluster"]				)[  # construct report dataframe
           numeric_cols
       ]  # group by cluster number
       .agg(
           [
               ("sum", np.sum),
               ("mean_with_zeros", lambda __lowerCamelCase				: np.mean(np.nan_to_num(__lowerCamelCase				)				)),
               ("mean_without_zeros", lambda __lowerCamelCase				: x.replace(0			,np.NaN				).mean()),
               (
                   "mean_25-75",
                   lambda __lowerCamelCase				: np.mean(
                       np.nan_to_num(
                           sorted(__lowerCamelCase				)[
                               round(len(__lowerCamelCase				) * 25 / 1_00				) : round(len(__lowerCamelCase				) * 75 / 1_00				)
                           ]				)				),
               ),
               ("mean_with_na", np.mean),
               ("min", lambda __lowerCamelCase				: x.min()),
               ("5%", lambda __lowerCamelCase				: x.quantile(0.05				)),
               ("25%", lambda __lowerCamelCase				: x.quantile(0.25				)),
               ("50%", lambda __lowerCamelCase				: x.quantile(0.50				)),
               ("75%", lambda __lowerCamelCase				: x.quantile(0.75				)),
               ("95%", lambda __lowerCamelCase				: x.quantile(0.95				)),
               ("max", lambda __lowerCamelCase				: x.max()),
               ("count", lambda __lowerCamelCase				: x.count()),
               ("stdev", lambda __lowerCamelCase				: x.std()),
               ("mode", lambda __lowerCamelCase				: x.mode()[0]),
               ("median", lambda __lowerCamelCase				: x.median()),
               ("# > 0", lambda __lowerCamelCase				: (x > 0).sum()),
           ]				)
       .T.reset_index()
       .rename(index=__lowerCamelCase			,columns={"level_0": "Features", "level_1": "Type"}				)
   )  # rename columns
   # calculate the size of cluster(count of clientID's)
   lowercase_    :str					    =				report[
       (report["Features"] == "dummy") & (report["Type"] == "count")
   ].copy()  # avoid SettingWithCopyWarning
   lowercase_    :List[str]					    =				(
       "ClusterSize"  # rename created cluster df to match report column names
   )
   lowercase_    :List[Any]					    =				"# of Customers"
   lowercase_    :Union[str, Any]					    =				pd.DataFrame(
       clustersize.iloc[:, 2:].values
       / clustersize.iloc[:, 2:].values.sum()				)
   lowercase_    :Union[str, Any]					    =				"% of Customers"  # rename created cluster df to match report column names
   lowercase_    :str					    =				"ClusterProportion"
   lowercase_    :Tuple					    =				clusterproportion.columns.tolist()
   lowercase_    :Any					    =				cols[-2:] + cols[:-2]
   lowercase_    :Any					    =				clusterproportion[cols]  # rearrange columns to match report
   lowercase_    :str					    =				report.columns
   lowercase_    :Dict					    =				pd.DataFrame(
       abs(
           report[report["Type"] == "count"].iloc[:, 2:].values
           - clustersize.iloc[:, 2:].values				)				)  # generating df with count of nan values
   lowercase_    :Dict					    =				0
   lowercase_    :Optional[int]					    =				"# of nan"
   lowercase_    :Any					    =				report[
       report["Type"] == "count"
   ].Features.tolist()  # filling values in order to match report
   lowercase_    :List[Any]					    =				a.columns.tolist()
   lowercase_    :Optional[Any]					    =				cols[-2:] + cols[:-2]
   lowercase_    :int					    =				a[cols]  # rearrange columns to match report
   lowercase_    :str					    =				report.columns  # rename columns to match report
   lowercase_    :Any					    =				report.drop(
       report[report.Type == "count"].index				)  # drop count values except cluster size
   lowercase_    :Tuple					    =				pd.concat(
       [report, a, clustersize, clusterproportion]			,axis=0				)  # concat report with clustert size and nan values
   lowercase_    :str					    =				report["Features"].isin(__lowerCamelCase				)
   lowercase_    :Union[str, Any]					    =				report.columns.tolist()
   lowercase_    :List[Any]					    =				cols[0:2] + cols[-1:] + cols[2:-1]
   lowercase_    :Any					    =				report[cols]
   lowercase_    :Dict					    =				{
       "ClusterSize": 9,
       "ClusterProportion": 8,
       "mean_with_zeros": 7,
       "mean_with_na": 6,
       "max": 5,
       "50%": 4,
       "min": 3,
       "25%": 2,
       "75%": 1,
       "# of nan": 0,
       "# > 0": -1,
       "sum_with_na": -2,
   }
   lowercase_    :Dict					    =				(
       report.assign(
           Sortera=lambda __lowerCamelCase				: x.Type.map(__lowerCamelCase				)			,Sortera=lambda __lowerCamelCase				: list(reversed(range(len(__lowerCamelCase				)				)				)				)			,)
       .sort_values(["Sorter1", "Mark", "Sorter2"]			,ascending=__lowerCamelCase				)
       .drop(["Sorter1", "Sorter2"]			,axis=1				)
   )
   lowercase_    :Union[str, Any]					    =				""
   lowercase_    :int					    =				report.reset_index()
   lowercase_    :List[str]					    =				report.drop(columns=["index"]				)
   return report


if __name__ == "__main__":
       import doctest

       doctest.testmod()









'''simple docstring'''


from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import center_crop, normalize, rescale, resize, to_channel_dimension_format
from ...image_utils import (
    IMAGENET_DEFAULT_MEAN,
    IMAGENET_DEFAULT_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    get_image_size,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, is_vision_available, logging


if is_vision_available():
 import PIL


lowerCAmelCase      :  Any      							=logging.get_logger(__name__)
class    a_     (       _lowerCAmelCase							):
     __A  				=    ["pixel_values"]





     def __init__(				self	:      Tuple			,   lowercase	:      bool = True			,   lowercase	:      Dict[str, int] = None			,   lowercase	:      bool = True			,   lowercase	:      Dict[str, int] = None			,   lowercase	:      PILImageResampling = PILImageResampling.BICUBIC			,   lowercase	:      bool = True			,   lowercase	:      Union[int, float] = 1 / 255			,   lowercase	:      bool = True			,   lowercase	:      Optional[Union[float, List[float]]] = None			,   lowercase	:      Optional[Union[float, List[float]]] = None			,   **lowercase	:      int			,   ):





        """simple docstring"""




        super().__init__(**lowercase		)
        lowercase_    :Dict					    =				crop_size if crop_size is not None else {"height": 256, "width": 256}
        lowercase_    :str					    =				get_size_dict(lowercase			,   param_name="crop_size"		)
        lowercase_    :Optional[Any]					    =				size if size is not None else {"height": 224, "width": 224}
        lowercase_    :Union[str, Any]					    =				get_size_dict(lowercase		)

        lowercase_    :Union[str, Any]					    =				do_center_crop
        lowercase_    :str					    =				crop_size
        lowercase_    :List[str]					    =				do_resize
        lowercase_    :str					    =				size
        lowercase_    :Tuple					    =				resample
        lowercase_    :int					    =				do_rescale
        lowercase_    :Union[str, Any]					    =				rescale_factor
        lowercase_    :Tuple					    =				do_normalize
        lowercase_    :List[Any]					    =				image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN
        lowercase_    :Optional[int]					    =				image_std if image_std is not None else IMAGENET_DEFAULT_STD





     def 							lowercase__   (				self	:      Any			,   lowercase	:      np.ndarray			,   lowercase	:      Dict[str, int]			,   lowercase	:      Optional[int] = None			,   lowercase	:      Optional[Union[str, ChannelDimension]] = None			,   **lowercase	:      List[Any]			,   ):





        """simple docstring"""




        lowercase_    :Dict					    =				self.size if size is None else size
        lowercase_    :Dict					    =				get_size_dict(lowercase		)
        lowercase_    :List[Any]					    =				get_size_dict(lowercase			,   param_name="crop_size"		)

        lowercase_    ,							lowercase_    :List[str]					    =				get_image_size(lowercase		)
        lowercase_    :List[str]					    =				min(lowercase			,   lowercase		)
        lowercase_    :Tuple					    =				(size["height"] / crop_size["height"]) * min_dim
        lowercase_    :int					    =				(size["width"] / crop_size["width"]) * min_dim
        return center_crop(lowercase			,   size=(cropped_height, cropped_width)			,   data_format=lowercase			,   **lowercase		)





     def 							lowercase__   (				self	:      Union[str, Any]			,   lowercase	:      np.ndarray			,   lowercase	:      Dict[str, int]			,   lowercase	:      PILImageResampling = PIL.Image.BICUBIC			,   lowercase	:      Optional[Union[str, ChannelDimension]] = None			,   **lowercase	:      List[str]			,   ):





        """simple docstring"""




        lowercase_    :Optional[int]					    =				get_size_dict(lowercase		)
        if "height" not in size or "width" not in size:
           raise ValueError(F'The size dictionary must contain the keys \'height\' and \'width\'. Got {size.keys()}'		)
        return resize(
            lowercase			,   size=(size["height"], size["width"])			,   resample=lowercase			,   data_format=lowercase			,   **lowercase		)





     def 							lowercase__   (				self	:      List[str]			,   lowercase	:      np.ndarray			,   lowercase	:      Union[int, float]			,   lowercase	:      Optional[Union[str, ChannelDimension]] = None			,   **lowercase	:      Union[str, Any]			,   ):





        """simple docstring"""




        return rescale(lowercase			,   scale=lowercase			,   data_format=lowercase			,   **lowercase		)





     def 							lowercase__   (				self	:      List[str]			,   lowercase	:      np.ndarray			,   lowercase	:      Union[float, List[float]]			,   lowercase	:      Union[float, List[float]]			,   lowercase	:      Optional[Union[str, ChannelDimension]] = None			,   **lowercase	:      str			,   ):





        """simple docstring"""




        return normalize(lowercase			,   mean=lowercase			,   std=lowercase			,   data_format=lowercase			,   **lowercase		)







     def 							lowercase__   (				self	:      List[Any]			,   lowercase	:      ImageInput			,   lowercase	:      Optional[bool] = None			,   lowercase	:      Optional[Dict[str, int]] = None			,   lowercase	:      Optional[bool] = None			,   lowercase	:      Optional[Dict[str, int]] = None			,   lowercase	:      PILImageResampling = None			,   lowercase	:      Optional[bool] = None			,   lowercase	:      Optional[float] = None			,   lowercase	:      Optional[bool] = None			,   lowercase	:      Optional[Union[float, List[float]]] = None			,   lowercase	:      Optional[Union[float, List[float]]] = None			,   lowercase	:      Optional[Union[str, TensorType]] = None			,   lowercase	:      ChannelDimension = ChannelDimension.FIRST			,   **lowercase	:      Optional[Any]			,   ):





        """simple docstring"""




        lowercase_    :str					    =				do_center_crop if do_center_crop is not None else self.do_center_crop
        lowercase_    :Union[str, Any]					    =				crop_size if crop_size is not None else self.crop_size
        lowercase_    :Optional[Any]					    =				get_size_dict(lowercase			,   param_name="crop_size"		)
        lowercase_    :Union[str, Any]					    =				do_resize if do_resize is not None else self.do_resize
        lowercase_    :Any					    =				size if size is not None else self.size
        lowercase_    :List[Any]					    =				get_size_dict(lowercase		)
        lowercase_    :Optional[Any]					    =				resample if resample is not None else self.resample
        lowercase_    :Dict					    =				do_rescale if do_rescale is not None else self.do_rescale
        lowercase_    :List[Any]					    =				rescale_factor if rescale_factor is not None else self.rescale_factor
        lowercase_    :str					    =				do_normalize if do_normalize is not None else self.do_normalize
        lowercase_    :Dict					    =				image_mean if image_mean is not None else self.image_mean
        lowercase_    :List[Any]					    =				image_std if image_std is not None else self.image_std

        lowercase_    :Any					    =				make_list_of_images(lowercase		)

        if not valid_images(lowercase		):
           raise ValueError(
               "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, "
               "torch.Tensor, tf.Tensor or jax.ndarray."		)

        if do_center_crop and crop_size is None:
           raise ValueError("If `do_center_crop` is set to `True`, `crop_size` must be provided."		)

        if do_resize and size is None:
           raise ValueError("Size must be specified if do_resize is True."		)

        if do_rescale and rescale_factor is None:
           raise ValueError("Rescale factor must be specified if do_rescale is True."		)

        if do_normalize and (image_mean is None or image_std is None):
           raise ValueError("Image mean and image standard deviation must be specified if do_normalize is True."		)

        # All transformations expect numpy arrays.
        lowercase_    :Optional[int]					    =				[to_numpy_array(lowercase		) for image in images]

        if do_center_crop:
           lowercase_    :str					    =				[self.center_crop(lowercase			,   lowercase			,   size=lowercase		) for image in images]

        if do_resize:
           lowercase_    :List[str]					    =				[self.resize(image=lowercase			,   size=lowercase			,   resample=lowercase		) for image in images]

        if do_rescale:
           lowercase_    :List[Any]					    =				[self.rescale(image=lowercase			,   scale=lowercase		) for image in images]

        if do_normalize:
           lowercase_    :Optional[Any]					    =				[self.normalize(image=lowercase			,   mean=lowercase			,   std=lowercase		) for image in images]

        lowercase_    :Optional[Any]					    =				[to_channel_dimension_format(lowercase			,   lowercase		) for image in images]

        lowercase_    :Union[str, Any]					    =				{"pixel_values": images}
        return BatchFeature(data=lowercase			,   tensor_type=lowercase		)


