



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")

_lowercase:				Optional[Any]       =	"K-MEANS-CLUST/ "






def 					a(   A :					Tuple				,  A :					Any				,  A :					Union[str, Any]=None )	-> List[Any]:
					"""simple docstring"""





					if seed is not None:  # useful for obtaining consistent results
										np.random.seed(A )
					a        =     data.shape[0]  # number of data points

					# Pick K indices from range [0, N).
					a        =     np.random.randint(0				,  A				,  A )

					# 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.
					a        =     data[rand_indices, :]

					return centroids






def 					a(   A :					Any				,  A :					Union[str, Any] )	-> Tuple:
					"""simple docstring"""





					return pairwise_distances(A				,  A				,  metric="euclidean" )






def 					a(   A :					List[Any]				,  A :					Optional[Any] )	-> Union[str, Any]:
					"""simple docstring"""





					a        =     centroid_pairwise_dist(A				,  A )

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

					return cluster_assignment






def 					a(   A :					Optional[int]				,  A :					str				,  A :					Tuple )	-> Optional[Any]:
					"""simple docstring"""





					a        =     []
					for i in range(A ):
										# Select all data points that belong to cluster i. Fill in the blank (RHS only)
										a        =     data[cluster_assignment == i]
										# Compute the mean of the data points. Fill in the blank (RHS only)
										a        =     member_data_points.mean(axis=0 )
										new_centroids.append(A )
					a        =     np.array(A )

					return new_centroids






def 					a(   A :					List[Any]				,  A :					Optional[int]				,  A :					Union[str, Any]				,  A :					Union[str, Any] )	-> Optional[Any]:
					"""simple docstring"""





					a        =     0.0
					for i in range(A ):
										# Select all data points that belong to cluster i. Fill in the blank (RHS only)
										a        =     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)
															a        =     pairwise_distances(
															    A				,  [centroids[i]]				,  metric="euclidean" )
															a        =     distances**2
															heterogeneity += np.sum(A )

					return heterogeneity






def 					a(   A :					List[str]				,  A :					List[str] )	-> Tuple:
					"""simple docstring"""





					plt.figure(figsize=(7, 4) )
					plt.plot(A				,  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 					a(   A :					Dict				,  A :					int				,  A :					Union[str, Any]				,  A :					Tuple=500				,  A :					str=None				,  A :					Optional[Any]=False )	-> int:
					"""simple docstring"""





					a        =     initial_centroids[:]
					a        =     None

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

										# 1. Make cluster assignments using nearest centroids
										a        =     assign_clusters(A				,  A )

										# 2. Compute a new centroid for each of the k clusters, averaging all data
										#    points assigned to that cluster.
										a        =     revise_centroids(A				,  A				,  A )

										# 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:
															a        =     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
															a        =     compute_heterogeneity(A				,  A				,  A				,  A )
															record_heterogeneity.append(A )

										a        =     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

		_lowercase:				int       =	ds.load_iris()
		_lowercase:				Any       =	3
		_lowercase:				Tuple       =	[]
		_lowercase:				Any       =	get_initial_centroids(dataset["data"], k, seed=0)
		_lowercase:				str       =	kmeans(
		    dataset["data"],
		    k,
		    initial_centroids,
		    maxiter=400,
		    record_heterogeneity=heterogeneity,
		    verbose=True,
		)
		plot_heterogeneity(heterogeneity, k)






def 					a(   A :					pd.DataFrame				,  A :					np.ndarray				,  A :					Any=None )	-> pd.DataFrame:
					"""simple docstring"""





					if fill_missing_report:
										a        =     df.fillna(value=A )
					a        =     1
					a        =     df.select_dtypes(np.number ).columns
					a        =     (
					    df.groupby(["Cluster"] )[  # construct report dataframe
					        numeric_cols
					    ]  # group by cluster number
					    .agg(
					        [
					            ("sum", np.sum),
					            ("mean_with_zeros", lambda A : np.mean(np.nan_to_num(A ) )),
					            ("mean_without_zeros", lambda A : x.replace(0				,  np.NaN ).mean()),
					            (
					                "mean_25-75",
					                lambda A : np.mean(
					                    np.nan_to_num(
					                        sorted(A )[
					                            round(len(A ) * 25 / 100 ) : round(len(A ) * 75 / 100 )
					                        ] ) ),
					            ),
					            ("mean_with_na", np.mean),
					            ("min", lambda A : x.min()),
					            ("5%", lambda A : x.quantile(0.05 )),
					            ("25%", lambda A : x.quantile(0.25 )),
					            ("50%", lambda A : x.quantile(0.50 )),
					            ("75%", lambda A : x.quantile(0.75 )),
					            ("95%", lambda A : x.quantile(0.95 )),
					            ("max", lambda A : x.max()),
					            ("count", lambda A : x.count()),
					            ("stdev", lambda A : x.std()),
					            ("mode", lambda A : x.mode()[0]),
					            ("median", lambda A : x.median()),
					            ("# > 0", lambda A : (x > 0).sum()),
					        ] )
					    .T.reset_index()
					    .rename(index=A				,  columns={"level_0": "Features", "level_1": "Type"} )
					)  # rename columns
					# calculate the size of cluster(count of clientID's)
					a        =     report[
					    (report["Features"] == "dummy") & (report["Type"] == "count")
					].copy()  # avoid SettingWithCopyWarning
					a        =     (
					    "ClusterSize"  # rename created cluster df to match report column names
					)
					a        =     "# of Customers"
					a        =     pd.DataFrame(
					    clustersize.iloc[:, 2:].values
					    / clustersize.iloc[:, 2:].values.sum() )
					a        =     "% of Customers"  # rename created cluster df to match report column names
					a        =     "ClusterProportion"
					a        =     clusterproportion.columns.tolist()
					a        =     cols[-2:] + cols[:-2]
					a        =     clusterproportion[cols]  # rearrange columns to match report
					a        =     report.columns
					a        =     pd.DataFrame(
					    abs(
					        report[report["Type"] == "count"].iloc[:, 2:].values
					        - clustersize.iloc[:, 2:].values ) )  # generating df with count of nan values
					a        =     0
					a        =     "# of nan"
					a        =     report[
					    report["Type"] == "count"
					].Features.tolist()  # filling values in order to match report
					a        =     a.columns.tolist()
					a        =     cols[-2:] + cols[:-2]
					a        =     a[cols]  # rearrange columns to match report
					a        =     report.columns  # rename columns to match report
					a        =     report.drop(
					    report[report.Type == "count"].index )  # drop count values except cluster size
					a        =     pd.concat(
					    [report, a, clustersize, clusterproportion]				,  axis=0 )  # concat report with clustert size and nan values
					a        =     report["Features"].isin(A )
					a        =     report.columns.tolist()
					a        =     cols[0:2] + cols[-1:] + cols[2:-1]
					a        =     report[cols]
					a        =     {
					    "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,
					}
					a        =     (
					    report.assign(
					        Sortera=lambda A : x.Type.map(A )				,  Sortera=lambda A : list(reversed(range(len(A ) ) ) )				,  )
					    .sort_values(["Sorter1", "Mark", "Sorter2"]				,  ascending=A )
					    .drop(["Sorter1", "Sorter2"]				,  axis=1 )
					)
					a        =     ""
					a        =     report.reset_index()
					a        =     report.drop(columns=["index"] )
					return report


if __name__ == "__main__":
		import doctest

		doctest.testmod()





import argparse

import torch

from transformers import ChineseCLIPConfig, ChineseCLIPModel






def 					a(   A :					Union[str, Any]				,  A :					List[str]				,  A :					Any )	-> Tuple:
					"""simple docstring"""





					a  ,       a  ,       a        =     pt_weights[f'''{prefix}.in_proj_weight'''].chunk(3				,  dim=0 )
					a  ,       a  ,       a        =     pt_weights[f'''{prefix}.in_proj_bias'''].chunk(3				,  dim=0 )

					a        =     pt_weights[f'''{prefix}.out_proj.weight''']
					a        =     pt_weights[f'''{prefix}.out_proj.bias''']

					a        =     q_proj
					a        =     q_proj_bias

					a        =     k_proj
					a        =     k_proj_bias

					a        =     v_proj
					a        =     v_proj_bias

					a        =     out_proj_weights
					a        =     out_proj_bias






def 					a(   A :					List[str]				,  A :					List[Any]				,  A :					int )	-> List[Any]:
					"""simple docstring"""





					copy_linear(hf_mlp.fca				,  A				,  f'''{prefix}.c_fc''' )
					copy_linear(hf_mlp.fca				,  A				,  f'''{prefix}.c_proj''' )






def 					a(   A :					Optional[Any]				,  A :					List[Any]				,  A :					List[str] )	-> Dict:
					"""simple docstring"""





					a        =     pt_weights[f'''{prefix}.weight'''].data
					a        =     pt_weights[f'''{prefix}.bias'''].data






def 					a(   A :					int				,  A :					Optional[Any]				,  A :					List[Any] )	-> Union[str, Any]:
					"""simple docstring"""





					copy_linear(hf_layer.layer_norma				,  A				,  f'''{prefix}.ln_1''' )
					copy_linear(hf_layer.layer_norma				,  A				,  f'''{prefix}.ln_2''' )

					# copy MLP
					copy_mlp(hf_layer.mlp				,  A				,  f'''{prefix}.mlp''' )

					# copy attn
					copy_attn_layer(hf_layer.self_attn				,  A				,  f'''{prefix}.attn''' )






def 					a(   A :					str				,  A :					Optional[int]				,  A :					List[str] )	-> Dict:
					"""simple docstring"""





					for layer_id, hf_layer in enumerate(A ):
										copy_layer(A				,  A				,  f'''{prefix}.{layer_id}''' )






def 					a(   A :					Dict				,  A :					Union[str, Any] )	-> Optional[Any]:
					"""simple docstring"""





					a        =     pt_weights["text_projection"].data.T

					# copy text encoder
					for name, param in hf_model.text_model.named_parameters():
										a        =     pt_weights[f'''bert.{name}'''].data






def 					a(   A :					Optional[Any]				,  A :					Optional[Any] )	-> List[str]:
					"""simple docstring"""





					a        =     pt_weights["visual.proj"].data.T

					# copy layer norms
					copy_linear(hf_model.vision_model.pre_layrnorm				,  A				,  "visual.ln_pre" )
					copy_linear(hf_model.vision_model.post_layernorm				,  A				,  "visual.ln_post" )

					# copy embeddings
					a        =     pt_weights["visual.conv1.weight"].data
					a        =     pt_weights["visual.class_embedding"].data
					a        =     pt_weights["visual.positional_embedding"].data

					# copy encoder
					copy_layers(hf_model.vision_model.encoder.layers				,  A				,  "visual.transformer.resblocks" )






@torch.no_grad()
def 					a(   A :					str				,  A :					List[str]				,  A :					Union[str, Any]=None )	-> Tuple:
					"""simple docstring"""





					assert config_path is not None, "Please specify the ChineseCLIP model config of the corresponding model size."
					a        =     ChineseCLIPConfig.from_pretrained(A )

					a        =     ChineseCLIPModel(A ).eval()

					a        =     torch.load(A				,  map_location="cpu" )["state_dict"]
					a        =     {(name[7:] if name.startswith("module." ) else name): value for name, value in pt_weights.items()}

					copy_text_model_and_projection(A				,  A )
					copy_vision_model_and_projection(A				,  A )
					a        =     pt_weights["logit_scale"].data

					hf_model.save_pretrained(A )


if __name__ == "__main__":
				_lowercase:				List[Any]       =	argparse.ArgumentParser()
				parser.add_argument(
				    "--pytorch_dump_folder_path",
				    default=None,
				    type=str,
				    help="Path to the output folder storing converted hf PyTorch model.",
				)
				parser.add_argument(
				    "--checkpoint_path", default=None, type=str, help="Path to original github format ChineseCLIP checkpoint."
				)
				parser.add_argument(
				    "--config_path", default=None, required=True, type=str, help="Path to hf config.json of model to convert."
				)
				_lowercase:				int       =	parser.parse_args()

				convert_chinese_clip_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path)
				print("The conversion is finished!")
