def _prepare_note_info(
    self,
    notes: pd.DataFrame,
    ratings: pd.DataFrame,
    noteStatusHistory: pd.DataFrame,
    prescoringRaterModelOutput: pd.DataFrame,
    pruneNotes: bool,
  ) -> pd.DataFrame:
    """Generate a DataFrame with one row per note containing all feature information.

    Note that some columns contain list values (e.g. a single column contains all
    Helpfulness ratings, where each rating is a unique string containing the rater ID
    and their Helpfulness rating).

    Args:
      notes: pd.DataFrame
      ratings: pd.DataFrame
      noteStatusHistory: pd.DataFrame
      prescoringRaterModelOutput: pd.DataFrame
      pruneNotes: True IFF noteInfo should be filtered to only include labeled data

    Returns:
      pd.DataFrame containing all feature information with one row per note.
    """
    # Augment rating with factors, and exclude ratings after status
    logger.info(f"total ratings considered for pflip model: {len(ratings)}")
    raterFactors = self._compute_rater_factors(prescoringRaterModelOutput)
    ratingCutoff = self._compute_rating_cutoff(noteStatusHistory)
    ratings = self._prepare_ratings(ratings, raterFactors, ratingCutoff)
    logger.info(f"total ratings before initial note status for pflip model: {len(ratings)}")
    # Identify set of labeled notes and prune ratings accordingly
    notes = self._get_recent_notes(notes, noteStatusHistory)
    if pruneNotes:
      labels = self._label_notes(noteStatusHistory)
      notes = notes.merge(labels)
      labelCounts = notes[LABEL].value_counts(dropna=False)
      logger.info(f"labels after restricting to recent notes:\n{labelCounts}")
      ratings = ratings.merge(notes[[c.noteIdKey]])
    logger.info(f"total ratings included in pflip model: {len(ratings)}")
    # Augment notes with features.  Note that attributes of the note (e.g. author,
    # creation time) should always be available because we filter to notes with the creation time
    # in the last year, inherently removing any deleted notes where the creation time is unavailable.
    helpfulnessRatings = self._get_helpfulness_ratings(notes[[c.noteIdKey]], ratings)
    notes = notes.merge(helpfulnessRatings, how="inner")
    noteAuthors = noteStatusHistory[[c.noteIdKey, c.noteAuthorParticipantIdKey]]
    notes = notes.merge(noteAuthors, how="inner")
    userHelpfulTags = self._get_user_tag_ratings(
      notes[[c.noteIdKey]], ratings, _USER_HELPFUL_TAGS, c.helpfulTagsTSVOrder
    )
    notes = notes.merge(userHelpfulTags, how="inner")
    userNotHelpfulTags = self._get_user_tag_ratings(
      notes[[c.noteIdKey]], ratings, _USER_NOT_HELPFUL_TAGS, c.notHelpfulTagsTSVOrder
    )
    notes = notes.merge(userNotHelpfulTags, how="inner")
    bucketCounts = self._get_bucket_count_totals(notes[[c.noteIdKey]], ratings)
    notes = notes.merge(bucketCounts, how="inner")
    helpfulStats = self._get_helpful_rating_stats(notes[[c.noteIdKey]], ratings)
    notes = notes.merge(helpfulStats, how="inner")
    tagRatios = self._get_tag_ratios(notes[[c.noteIdKey]], ratings)
    notes = notes.merge(tagRatios, how="inner")
    return notes
Generate a DataFrame with one row per note containing all feature information.

    Note that some columns contain list values (e.g. a single column contains all
    Helpfulness ratings, where each rating is a unique string containing the rater ID
    and their Helpfulness rating).

    Args:
      notes: pd.DataFrame
      ratings: pd.DataFrame
      noteStatusHistory: pd.DataFrame
      prescoringRaterModelOutput: pd.DataFrame
      pruneNotes: True IFF noteInfo should be filtered to only include labeled data

    Returns:
      pd.DataFrame containing all feature information with one row per note.
    
sourcecode/scoring/pflip_model.py