code: def _k_prototypes_iter(
      Xnum,
      Xcat,
      centroids,
      cl_attr_sum,
      cl_memb_sum,
      cl_attr_freq,
      membship,
      num_dissim,
      cat_dissim,
      gamma,
      random_state,
      sample_weight,
  ):
      """Single iteration of the k-prototypes algorithm"""
      moves = 0
      for ipoint in range(Xnum.shape[0]):
          weight = (
              sample_weight[ipoint] if sample_weight is not None else 1
          )
          clust = np.argmin(
              num_dissim(centroids[0], Xnum[ipoint])
              + gamma
              * cat_dissim(
                  centroids[1], Xcat[ipoint], X=Xcat, membship=membship
              )
          )
          if membship[clust, ipoint]:
              # Point is already in its right place.
              continue
  
          # Move point, and update old/new cluster frequencies and centroids.
          moves += 1
          old_clust = np.argwhere(membship[:, ipoint])[0][0]
  
          # Note that membship gets updated by kmodes.move_point_cat.
          # move_point_num only updates things specific to the k-means part.
          cl_attr_sum, cl_memb_sum = _move_point_num(
              Xnum[ipoint],
              clust,
              old_clust,
              cl_attr_sum,
              cl_memb_sum,
              weight,
          )
          # noinspection PyProtectedMember
          cl_attr_freq, membship, centroids[1] = kmodes._move_point_cat(
              Xcat[ipoint],
              ipoint,
              clust,
              old_clust,
              cl_attr_freq,
              membship,
              centroids[1],
              weight,
          )
  
          # Update old and new centroids for numerical attributes using
          # the means and sums of all values
          for iattr in range(len(Xnum[ipoint])):
              for curc in (clust, old_clust):
                  if cl_memb_sum[curc]:
                      centroids[0][curc, iattr] = (
                          cl_attr_sum[curc, iattr] / cl_memb_sum[curc]
                      )
                  else:
                      centroids[0][curc, iattr] = 0.0
  
          # In case of an empty cluster, reinitialize with a random point
          # from largest cluster.
          if not cl_memb_sum[old_clust]:
              from_clust = membship.sum(axis=1).argmax()
              choices = [
                  ii
                  for ii, ch in enumerate(membship[from_clust, :])
                  if ch
              ]
              rindx = random_state.choice(choices)
  
              cl_attr_sum, cl_memb_sum = _move_point_num(
                  Xnum[rindx],
                  old_clust,
                  from_clust,
                  cl_attr_sum,
                  cl_memb_sum,
                  weight,
              )
              (
                  cl_attr_freq,
                  membship,
                  centroids[1],
              ) = kmodes._move_point_cat(
                  Xcat[rindx],
                  rindx,
                  old_clust,
                  from_clust,
                  cl_attr_freq,
                  membship,
                  centroids[1],
                  weight,
              )
  
      return (
          centroids,
          cl_attr_sum,
          cl_memb_sum,
          cl_attr_freq,
          membship,
          moves,
      )
  
imports: from collections import defaultdict
  import numpy
  from joblib import Parallel, delayed
  from scipy import sparse
  from sklearn.utils import check_random_state
  from sklearn.utils.validation import check_array
  from .None import kmodes
  from .util import get_max_value_key, encode_features, get_unique_rows, decode_centroids, pandas_to_numpy
  from .util.dissim import matching_dissim, euclidean_dissim
  from .util.init_methods import init_cao, init_huang
label_desc: Use image node_id 4 for calling a global function with example usage: _k_prototypes_iter(Xnum, Xcat, centroids, cl_attr_sum, cl_memb_sum, cl_attr_freq, membship, num_dissim, cat_dissim, gamma, random_state, sample_weight) and returns: centroids,  cl_attr_sum,  cl_memb_sum,  cl_attr_freq,  membship,  moves