def compute_association_matrix_of_groups(adata: AnnData, prediction: str, reference: str, normalization: Literal[('prediction', 'reference')]='prediction', threshold: float=0.01, max_n_names: Optional[int]=2):
    'Compute overlaps between groups.\n\n    See ``identify_groups`` for identifying the groups.\n\n    Parameters\n    ----------\n    adata\n    prediction\n        Field name of adata.obs.\n    reference\n        Field name of adata.obs.\n    normalization\n        Whether to normalize with respect to the predicted groups or the\n        reference groups.\n    threshold\n        Do not consider associations whose overlap is below this fraction.\n    max_n_names\n        Control how many reference names you want to be associated with per\n        predicted name. Set to `None`, if you want all.\n\n    Returns\n    -------\n    asso_names\n        List of associated reference names\n        (`max_n_names` for each predicted name).\n    asso_matrix\n        Matrix where rows correspond to the predicted labels and columns to the\n        reference labels, entries are proportional to degree of association.\n    '
    if (normalization not in {'prediction', 'reference'}):
        raise ValueError('`normalization` needs to be either "prediction" or "reference".')
    sanitize_anndata(adata)
    cats = adata.obs[reference].cat.categories
    for cat in cats:
        if (cat in settings.categories_to_ignore):
            logg.info(f'Ignoring category {cat!r} as it’s in `settings.categories_to_ignore`.')
    asso_names = []
    asso_matrix = []
    for (ipred_group, pred_group) in enumerate(adata.obs[prediction].cat.categories):
        if ('?' in pred_group):
            pred_group = str(ipred_group)
        mask_pred = (adata.obs[prediction].values == pred_group)
        mask_pred_int = mask_pred.astype(np.int8)
        asso_matrix += [[]]
        for ref_group in adata.obs[reference].cat.categories:
            mask_ref = (adata.obs[reference].values == ref_group).astype(np.int8)
            mask_ref_or_pred = mask_ref.copy()
            mask_ref_or_pred[mask_pred] = 1
            if (normalization == 'prediction'):
                ratio_contained = ((np.sum(mask_pred_int) - np.sum((mask_ref_or_pred - mask_ref))) / np.sum(mask_pred_int))
            else:
                ratio_contained = ((np.sum(mask_ref) - np.sum((mask_ref_or_pred - mask_pred_int))) / np.sum(mask_ref))
            asso_matrix[(- 1)] += [ratio_contained]
        name_list_pred = [(cats[i] if (cats[i] not in settings.categories_to_ignore) else '') for i in np.argsort(asso_matrix[(- 1)])[::(- 1)] if (asso_matrix[(- 1)][i] > threshold)]
        asso_names += ['\n'.join(name_list_pred[:max_n_names])]
    Result = namedtuple('compute_association_matrix_of_groups', ['asso_names', 'asso_matrix'])
    return Result(asso_names=asso_names, asso_matrix=np.array(asso_matrix))
Compute overlaps between groups.

See ``identify_groups`` for identifying the groups.

Parameters
----------
adata
prediction
    Field name of adata.obs.
reference
    Field name of adata.obs.
normalization
    Whether to normalize with respect to the predicted groups or the
    reference groups.
threshold
    Do not consider associations whose overlap is below this fraction.
max_n_names
    Control how many reference names you want to be associated with per
    predicted name. Set to `None`, if you want all.

Returns
-------
asso_names
    List of associated reference names
    (`max_n_names` for each predicted name).
asso_matrix
    Matrix where rows correspond to the predicted labels and columns to the
    reference labels, entries are proportional to degree of association.
def compute_association_matrix_of_groups(adata: AnnData, prediction: str, reference: str, normalization: Literal[('prediction', 'reference')]='prediction', threshold: float=0.01, max_n_names: Optional[int]=2):
    'Compute overlaps between groups.\n\n    See ``identify_groups`` for identifying the groups.\n\n    Parameters\n    ----------\n    adata\n    prediction\n        Field name of adata.obs.\n    reference\n        Field name of adata.obs.\n    normalization\n        Whether to normalize with respect to the predicted groups or the\n        reference groups.\n    threshold\n        Do not consider associations whose overlap is below this fraction.\n    max_n_names\n        Control how many reference names you want to be associated with per\n        predicted name. Set to `None`, if you want all.\n\n    Returns\n    -------\n    asso_names\n        List of associated reference names\n        (`max_n_names` for each predicted name).\n    asso_matrix\n        Matrix where rows correspond to the predicted labels and columns to the\n        reference labels, entries are proportional to degree of association.\n    '
    if (normalization not in {'prediction', 'reference'}):
        raise ValueError('`normalization` needs to be either "prediction" or "reference".')
    sanitize_anndata(adata)
    cats = adata.obs[reference].cat.categories
    for cat in cats:
        if (cat in settings.categories_to_ignore):
            logg.info(f'Ignoring category {cat!r} as it’s in `settings.categories_to_ignore`.')
    asso_names = []
    asso_matrix = []
    for (ipred_group, pred_group) in enumerate(adata.obs[prediction].cat.categories):
        if ('?' in pred_group):
            pred_group = str(ipred_group)
        mask_pred = (adata.obs[prediction].values == pred_group)
        mask_pred_int = mask_pred.astype(np.int8)
        asso_matrix += [[]]
        for ref_group in adata.obs[reference].cat.categories:
            mask_ref = (adata.obs[reference].values == ref_group).astype(np.int8)
            mask_ref_or_pred = mask_ref.copy()
            mask_ref_or_pred[mask_pred] = 1
            if (normalization == 'prediction'):
                ratio_contained = ((np.sum(mask_pred_int) - np.sum((mask_ref_or_pred - mask_ref))) / np.sum(mask_pred_int))
            else:
                ratio_contained = ((np.sum(mask_ref) - np.sum((mask_ref_or_pred - mask_pred_int))) / np.sum(mask_ref))
            asso_matrix[(- 1)] += [ratio_contained]
        name_list_pred = [(cats[i] if (cats[i] not in settings.categories_to_ignore) else ) for i in np.argsort(asso_matrix[(- 1)])[::(- 1)] if (asso_matrix[(- 1)][i] > threshold)]
        asso_names += ['\n'.join(name_list_pred[:max_n_names])]
    Result = namedtuple('compute_association_matrix_of_groups', ['asso_names', 'asso_matrix'])
    return Result(asso_names=asso_names, asso_matrix=np.array(asso_matrix))