[Python] fastest way to search 5k rows inside of 100m dataframe

Discussão em 'Python' iniciado por Stack, Março 30, 2025.

  1. Stack

    Stack Membro Participativo

    I am not sure title is well describes the problem but I will explain it step by step.

    I have a correlation matrix of genes (10k x 10k) I convert this correlation matrix to pairwise dataframe (upper triangle) (around 100m row)

    [​IMG]

    Then I have gold-standard TERMS table around 5k rows and columns are ID and used_genes

    [​IMG]

    What I do:

    I iterate of each Gold-standard complex row.

    Convert used_gene list to pairwise, like geneA-geneB, geneA-geneC etc.

    Check those complex-row gene pairs in the stacked correlation pairs.

    If they are exist I put column TP=1, if not TP=0.

    Based on the TP counts I calculate precision, recall, and area under the curve score.

    [​IMG]

    I will share my function below, with 100m stacked df, and 5k terms It takes around 25 minutes, and I am trying to find a way to reduce the time.

    def compute_per_complex_pr(corr_matrix, terms_df):

    pairwise_df = binary(corr_matrix)
    pairwise_df = quick_sort(pairwise_df).reset_index(drop=True)

    # Precompute a mapping from each gene to the row indices in the pairwise DataFrame where it appears.
    gene_to_pair_indices = {}
    for i, (gene_a, gene_b) in enumerate(zip(pairwise_df["gene1"], pairwise_df["gene2"])):
    gene_to_pair_indices.setdefault(gene_a, []).append(i)
    gene_to_pair_indices.setdefault(gene_b, []).append(i)

    # Initialize AUC scores (one for each complex) with NaNs.
    auc_scores = np.full(len(terms_df), np.nan)

    # Loop over each gene complex
    for idx, row in terms_df.iterrows():
    gene_set = set(row.used_genes)
    if len(gene_set) < min_complex_size: # Skip small complexes.
    continue

    # Collect all row indices in the pairwise data where either gene belongs to the complex.
    candidate_indices = set()
    for gene in gene_set:
    candidate_indices.update(gene_to_pair_indices.get(gene, []))
    candidate_indices = sorted(candidate_indices)

    if not candidate_indices:
    continue

    # Select only the relevant pairwise comparisons.
    sub_df = pairwise_df.loc[candidate_indices]
    # A prediction is 1 if both genes in the pair are in the complex; otherwise 0.
    predictions = (sub_df["gene1"].isin(gene_set) & sub_df["gene2"].isin(gene_set)).astype(int)

    if predictions.sum() == 0:
    continue

    # Compute cumulative true positives and derive precision and recall.
    true_positive_cumsum = predictions.cumsum()
    precision = true_positive_cumsum / (np.arange(len(predictions)) + 1)
    recall = true_positive_cumsum / true_positive_cumsum.iloc[-1]

    if len(recall) < 2 or recall.iloc[-1] == 0:
    continue

    auc_scores[idx] = metrics.auc(recall, precision)

    # Add the computed AUC scores to the terms DataFrame.
    terms_df["auc_score"] = auc_scores
    return terms_df

    Continue reading...

Compartilhe esta Página