code: def apply_model(
      key: Tuple,
      key_pattern: List[str],
      pdf: pd.DataFrame,
      labeldf: pd.DataFrame,
      sample_index: Dict[str, List[str]],
      alphas: Dict[str, Float],
      covdf: pd.DataFrame,
  ) -> pd.DataFrame:
      """
      This function takes a block X and a coefficient matrix B and performs the multiplication X*B.  The matrix resulting
      from this multiplication represents a block in a new, dimensionally-reduced block matrix.
  
      Args:
          key : unique key identifying the group of rows emitted by a groupBy statement
          key_pattern : pattern of columns used in the groupBy statement that emitted this group of rows
          pdf : starting Pandas DataFrame containing the lists of rows used to assemble block X and coefficients B
              identified by :key:
              schema:
                   |-- header_block: string
                   |-- sample_block: string
                   |-- header: string
                   |-- size: integer
                   |-- indices: array
                   |    |-- element: integer
                   |-- values: array
                   |    |-- element: double
                   |-- sort_key: integer
                   |-- mu: double
                   |-- sig: double
                   |-- alphas: array
                   |    |-- element: string
                   |-- labels: array
                   |    |-- element: string
                   |-- coefficients: array
                   |    |-- element: double
          labeldf : Pandas DataFrame containing label values that were used in fitting coefficient matrix B.
          sample_index : sample_index: dict containing a mapping of sample_block ID to a list of corresponding sample IDs
          alphas : dict of {alphaName : alphaValue} for the alpha values that were used when fitting coefficient matrix B
          covdf: Pandas DataFrame containing covariates that should be included with every block X above (can be empty).
  
      Returns:
          transformed Pandas DataFrame containing reduced matrix block produced by the multiplication X*B
              schema (specified by reduced_matrix_struct):
                   |-- header: string
                   |-- size: integer
                   |-- values: array
                   |    |-- element: double
                   |-- header_block: string
                   |-- sample_block: string
                   |-- sort_key: integer
                   |-- mu: double
                   |-- sig: double
                   |-- alpha: string
                   |-- label: string
      """
  
      (
          header_block,
          sample_block,
          label,
      ) = parse_header_block_sample_block_label(key, key_pattern)
      sort_in_place(pdf, ["sort_key"])
  
      if covdf.empty:
          n_rows = pdf["size"][0]
          n_cols = len(pdf)
          X = assemble_block(
              n_rows, n_cols, pdf, np.array([]), np.array([])
          )
      else:
          sample_list = sample_index[sample_block]
          n_rows = int(pdf[~pdf["values"].isnull()]["size"].array[0])
          n_cols = len(pdf[~pdf["values"].isnull()])
          cov_matrix = slice_label_rows(
              covdf, "all", sample_list, np.array([])
          )
          X = assemble_block(
              n_rows,
              n_cols,
              pdf[~pdf["values"].isnull()],
              cov_matrix,
              np.array([]),
          )
  
      B = np.row_stack(pdf["coefficients"].array)
      XB = X @ B
      mu, sig = XB.mean(axis=0), XB.std(axis=0)
      alpha_names = sorted(alphas.keys())
      row_indexer = cross_alphas_and_labels(alpha_names, labeldf, label)
      alpha_col, label_col = zip(*row_indexer)
      new_header_block, sort_key_col, header_col = new_headers(
          header_block, alpha_names, row_indexer
      )
  
      data = {
          "header": header_col,
          "size": X.shape[0],
          "values": list(XB.T),
          "header_block": new_header_block,
          "sample_block": sample_block,
          "sort_key": sort_key_col,
          "mu": mu,
          "sig": sig,
          "alpha": alpha_col,
          "label": label_col,
      }
  
      return pd.DataFrame(data)
  
file_path: glow/python/glow/wgr/ridge_udfs.py
imports: from glow.wgr.model_functions import *
  from nptyping import Float
  import pandas
  from pyspark.sql.types import ArrayType, IntegerType, StructType, StructField, StringType, DoubleType
  from typeguard import typechecked
  from typing import Dict, List
label_desc: Use image node_id 4 for calling a global function with example usage: apply_model(key, key_pattern, pdf, labeldf, sample_index, alphas, covdf) and returns: pd