code: def apply_logistic_model(
      key: Tuple,
      key_pattern: List[str],
      pdf: pd.DataFrame,
      labeldf: pd.DataFrame,
      sample_blocks: Dict[str, List[str]],
      alphas: Dict[str, Float],
      covdf: pd.DataFrame,
  ) -> pd.DataFrame:
      """
      This function takes a block X and a coefficient matrix B, performs the multiplication X*B, and returns sigmoid(X*B),
      representing the output of the logistic model p(y|X) = sigmoid(XB).
  
      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
                   |-- 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 logistic_reduced_matrix_struct):
                   |-- header: string
                   |-- size: integer
                   |-- values: array
                   |    |-- element: double
                   |-- header_block: string
                   |-- sample_block: string
                   |-- sort_key: integer
                   |-- 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 there is a covdf, we will have null 'values' entries in pdf arising from the right join of blockdf
      # to modeldf, so we will filter those rows out before assembling the block.
      sample_list = sample_blocks[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
      P = sigmoid(XB)
      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(P.T),
          "header_block": new_header_block,
          "sample_block": sample_block,
          "sort_key": sort_key_col,
          "alpha": alpha_col,
          "label": label_col,
      }
  
      return pd.DataFrame(data)
  
imports: from .ridge_udfs import *
label_desc: Use image node_id 4 for calling a global function with example usage: apply_logistic_model(key, key_pattern, pdf, labeldf, sample_blocks, alphas, covdf) and returns: pd