def pivot_to_losses(dataframe, index_on=None):
    """Generates a dataframe of losses
    
    Args:
        dataframe (pandas.DataFrame): Output of load_contention_datasets
        index_on (list or None): Index on listed columns in addition to
            dataset_id and primary_nodes (default: "workload")

    Returns:
        pandas.DataFrame
    """
    if index_on is None:
        pivoted_df = dataframe.pivot_table(
            index=["dataset_id", "workload", "primary_nodes"],
            values=["performance"],
            columns=["contention"])
    elif isinstance(index_on, list):
        pivoted_df = dataframe.pivot_table(
            index=["dataset_id"] + index_on + ["primary_nodes"],
            values=["performance"],
            columns=["contention"])
    elif isinstance(index_on, str):
        pivoted_df = dataframe.pivot_table(
            index=["dataset_id"] + [index_on] + ["primary_nodes"],
            values=["performance"],
            columns=["contention"])
    else:
        raise ValueError("index_on is invalid type {}".format(type(index_on)))

    # set columns to be quiet or noisy and get rid of other multilevel columns
    pivoted_df.columns = pivoted_df.columns.get_level_values(1)

    pivoted_df["loss"] = pivoted_df["quiet"] - pivoted_df["noisy"]
    pivoted_df["loss%"] = pivoted_df["loss"] / pivoted_df["quiet"]

    return pivoted_df