def identify_groups(ref_labels, pred_labels, return_overlaps=False):
    'Which predicted label explains which reference label?\n\n    A predicted label explains the reference label which maximizes the minimum\n    of ``relative_overlaps_pred`` and ``relative_overlaps_ref``.\n\n    Compare this with ``compute_association_matrix_of_groups``.\n\n    Returns\n    -------\n    A dictionary of length ``len(np.unique(ref_labels))`` that stores for each\n    reference label the predicted label that best explains it.\n\n    If ``return_overlaps`` is ``True``, this will in addition return the overlap\n    of the reference group with the predicted group; normalized with respect to\n    the reference group size and the predicted group size, respectively.\n    '
    (ref_unique, ref_counts) = np.unique(ref_labels, return_counts=True)
    ref_dict = dict(zip(ref_unique, ref_counts))
    (pred_unique, pred_counts) = np.unique(pred_labels, return_counts=True)
    pred_dict = dict(zip(pred_unique, pred_counts))
    associated_predictions = {}
    associated_overlaps = {}
    for ref_label in ref_unique:
        (sub_pred_unique, sub_pred_counts) = np.unique(pred_labels[(ref_label == ref_labels)], return_counts=True)
        relative_overlaps_pred = [(sub_pred_counts[i] / pred_dict[n]) for (i, n) in enumerate(sub_pred_unique)]
        relative_overlaps_ref = [(sub_pred_counts[i] / ref_dict[ref_label]) for (i, n) in enumerate(sub_pred_unique)]
        relative_overlaps = np.c_[(relative_overlaps_pred, relative_overlaps_ref)]
        relative_overlaps_min = np.min(relative_overlaps, axis=1)
        pred_best_index = np.argsort(relative_overlaps_min)[::(- 1)]
        associated_predictions[ref_label] = sub_pred_unique[pred_best_index]
        associated_overlaps[ref_label] = relative_overlaps[pred_best_index]
    if return_overlaps:
        return (associated_predictions, associated_overlaps)
    else:
        return associated_predictions
Which predicted label explains which reference label?

A predicted label explains the reference label which maximizes the minimum
of ``relative_overlaps_pred`` and ``relative_overlaps_ref``.

Compare this with ``compute_association_matrix_of_groups``.

Returns
-------
A dictionary of length ``len(np.unique(ref_labels))`` that stores for each
reference label the predicted label that best explains it.

If ``return_overlaps`` is ``True``, this will in addition return the overlap
of the reference group with the predicted group; normalized with respect to
the reference group size and the predicted group size, respectively.
def identify_groups(ref_labels, pred_labels, return_overlaps=False):
    'Which predicted label explains which reference label?\n\n    A predicted label explains the reference label which maximizes the minimum\n    of ``relative_overlaps_pred`` and ``relative_overlaps_ref``.\n\n    Compare this with ``compute_association_matrix_of_groups``.\n\n    Returns\n    -------\n    A dictionary of length ``len(np.unique(ref_labels))`` that stores for each\n    reference label the predicted label that best explains it.\n\n    If ``return_overlaps`` is ``True``, this will in addition return the overlap\n    of the reference group with the predicted group; normalized with respect to\n    the reference group size and the predicted group size, respectively.\n    '
    (ref_unique, ref_counts) = np.unique(ref_labels, return_counts=True)
    ref_dict = dict(zip(ref_unique, ref_counts))
    (pred_unique, pred_counts) = np.unique(pred_labels, return_counts=True)
    pred_dict = dict(zip(pred_unique, pred_counts))
    associated_predictions = {}
    associated_overlaps = {}
    for ref_label in ref_unique:
        (sub_pred_unique, sub_pred_counts) = np.unique(pred_labels[(ref_label == ref_labels)], return_counts=True)
        relative_overlaps_pred = [(sub_pred_counts[i] / pred_dict[n]) for (i, n) in enumerate(sub_pred_unique)]
        relative_overlaps_ref = [(sub_pred_counts[i] / ref_dict[ref_label]) for (i, n) in enumerate(sub_pred_unique)]
        relative_overlaps = np.c_[(relative_overlaps_pred, relative_overlaps_ref)]
        relative_overlaps_min = np.min(relative_overlaps, axis=1)
        pred_best_index = np.argsort(relative_overlaps_min)[::(- 1)]
        associated_predictions[ref_label] = sub_pred_unique[pred_best_index]
        associated_overlaps[ref_label] = relative_overlaps[pred_best_index]
    if return_overlaps:
        return (associated_predictions, associated_overlaps)
    else:
        return associated_predictions