def aggregate_named_reports(named_reports: Dict[(str, Dict[(str, Metric)])], micro_average: bool=False) -> Dict[(str, Metric)]:
    '\n    Aggregate metrics from multiple reports.\n\n    :param reports:\n        Dict of tasks -> metrics.\n    :param micro_average:\n        If true, top level metrics will be the micro average. By default, we\n        use macro average.\n    :return:\n        The aggregated report\n    '
    if (len(named_reports) == 0):
        raise ValueError('Cannot aggregate empty reports.')
    if (len(named_reports) == 1):
        return next(iter(named_reports.values()))
    m: Dict[(str, Metric)] = {}
    macro_averages: Dict[(str, Dict[(str, Metric)])] = {}
    for (task_id, task_report) in named_reports.items():
        for (each_metric, value) in task_report.items():
            if value.is_global:
                if (each_metric not in m):
                    m[each_metric] = value
            else:
                task_metric = f'{task_id}/{each_metric}'
                m[task_metric] = (m.get(task_metric) + value)
                if (micro_average or (not value.macro_average)):
                    m[each_metric] = (m.get(each_metric) + value)
                else:
                    if (each_metric not in macro_averages):
                        macro_averages[each_metric] = {}
                    macro_averages[each_metric][task_id] = value
    for (key, values) in macro_averages.items():
        m[key] = MacroAverageMetric(values)
    return m
Aggregate metrics from multiple reports.

:param reports:
    Dict of tasks -> metrics.
:param micro_average:
    If true, top level metrics will be the micro average. By default, we
    use macro average.
:return:
    The aggregated report
def aggregate_named_reports(named_reports: Dict[(str, Dict[(str, Metric)])], micro_average: bool=False) -> Dict[(str, Metric)]:
    '\n    Aggregate metrics from multiple reports.\n\n    :param reports:\n        Dict of tasks -> metrics.\n    :param micro_average:\n        If true, top level metrics will be the micro average. By default, we\n        use macro average.\n    :return:\n        The aggregated report\n    '
    if (len(named_reports) == 0):
        raise ValueError('Cannot aggregate empty reports.')
    if (len(named_reports) == 1):
        return next(iter(named_reports.values()))
    m: Dict[(str, Metric)] = {}
    macro_averages: Dict[(str, Dict[(str, Metric)])] = {}
    for (task_id, task_report) in named_reports.items():
        for (each_metric, value) in task_report.items():
            if value.is_global:
                if (each_metric not in m):
                    m[each_metric] = value
            else:
                task_metric = f'{task_id}/{each_metric}'
                m[task_metric] = (m.get(task_metric) + value)
                if (micro_average or (not value.macro_average)):
                    m[each_metric] = (m.get(each_metric) + value)
                else:
                    if (each_metric not in macro_averages):
                        macro_averages[each_metric] = {}
                    macro_averages[each_metric][task_id] = value
    for (key, values) in macro_averages.items():
        m[key] = MacroAverageMetric(values)
    return m