def METHOD_NAME(df: pd.DataFrame) -> pd.DataFrame:
    """
    The NYT anomaly data is normalized such that each row can represent an
    anomaly for multiple dates, locations, and metrics. We want to denormalize
    it so that each row represents a single date+location+metric anomaly.
    """
    # Look for rows with an end_date and create separate rows for each date in the [date, end_date] range.
    def date_range_for_row(row: pd.Series):
        return pd.date_range(
            row[NYTimesFields.DATE],
            row[NYTimesFields.DATE]
            if pd.isna(row[NYTimesFields.END_DATE])
            else row[NYTimesFields.END_DATE],
            freq="d",
        )
    df = df.assign(date=df.apply(date_range_for_row, axis=1), end_date=pd.NaT,).explode(
        NYTimesFields.DATE
    )
    # Look for state rows with omit_from_rolling_average_on_subgeographies and add new rows for each county within the state
    omit_subgeographies_mask = (
        df[NYTimesFields.OMIT_FROM_ROLLING_AVERAGE_ON_SUBGEOGRAPHIES] == "yes"
    ) & (df[CommonFields.FIPS].str.len() == 2)
    df_subgeography_rows = df.loc[omit_subgeographies_mask].copy()
    df_subgeography_rows = df_subgeography_rows.assign(
        fips=df_subgeography_rows.apply(
            lambda row: _get_county_fips_codes_for_state(row[CommonFields.FIPS]), axis=1
        ),
        omit_from_rolling_average="yes",
    ).explode(CommonFields.FIPS)
    df = df.append(df_subgeography_rows)
    # Look for rows with type=='both' and replace with two rows ('cases' and 'deaths')
    df = df.assign(
        type=df.apply(
            lambda row: ["cases", "deaths"]
            if row[NYTimesFields.TYPE] == "both"
            else row[NYTimesFields.TYPE],
            axis=1,
        )
    ).explode(NYTimesFields.TYPE)
    return df.reset_index()