From 19512ebde8f75a5bfabf5981c542bd68e2cd05d5 Mon Sep 17 00:00:00 2001 From: axiomcura Date: Mon, 16 Dec 2024 11:41:06 -0700 Subject: [PATCH 01/21] added doc strings and inline comments --- src/copairs/compute.py | 493 ++++++++++++++++++++++++--- src/copairs/map/average_precision.py | 208 ++++++++++- src/copairs/map/filter.py | 138 +++++++- src/copairs/map/map.py | 51 ++- 4 files changed, 820 insertions(+), 70 deletions(-) diff --git a/src/copairs/compute.py b/src/copairs/compute.py index 954bf01..141d517 100644 --- a/src/copairs/compute.py +++ b/src/copairs/compute.py @@ -2,19 +2,42 @@ import os from multiprocessing.pool import ThreadPool from pathlib import Path -from typing import Callable +from typing import Callable, Tuple import numpy as np from tqdm.autonotebook import tqdm -def parallel_map(par_func, items): - """Execute par_func(i) for every i in items using ThreadPool and tqdm.""" +def parallel_map(par_func: Callable[[int], None], items: np.ndarray) -> None: + """Execute a function in parallel over a list of items. + + This function uses a thread pool to process items in parallel, with progress + tracking via `tqdm`. It is particularly useful for batch operations that benefit + from multithreading. + + Parameters: + ---------- + par_func : Callable + A function to execute for each item. It should accept a single argument + (an item index or value). + items : np.ndarray + An array or list of items to process. + """ + # Total number of items to process num_items = len(items) + + # Determine the number of threads to use, limited by CPU count pool_size = min(num_items, os.cpu_count()) + + # Calculate chunk size for dividing work among threads chunksize = num_items // pool_size + + # Use a thread pool to execute the function in parallel with ThreadPool(pool_size) as pool: + # Map the function to items with unordered execution for better efficiency tasks = pool.imap_unordered(par_func, items, chunksize=chunksize) + + # Display progress using tqdm for _ in tqdm(tasks, total=len(items), leave=False): pass @@ -22,18 +45,40 @@ def parallel_map(par_func, items): def batch_processing( pairwise_op: Callable[[np.ndarray, np.ndarray], np.ndarray], ): - """Decorator adding the batch_size param to run the function with - multithreading using a list of paired indices""" + """Decorator for adding batch processing to pairwise operations. + + This function wraps a pairwise operation to process data in batches, enabling + efficient computation and multithreading when working with large datasets. + + Parameters: + ---------- + pairwise_op : Callable + A function that computes pairwise operations (e.g., similarity or distance) + between two arrays of features. + + Returns: + ------- + Callable + A wrapped function that processes pairwise operations in batches. + + """ def batched_fn(feats: np.ndarray, pair_ix: np.ndarray, batch_size: int): + # Total number of pairs to process num_pairs = len(pair_ix) + + # Initialize an empty result array to store pairwise operation results result = np.empty(num_pairs, dtype=np.float32) def par_func(i): + # Extract the features for the current batch of pairs x_sample = feats[pair_ix[i : i + batch_size, 0]] y_sample = feats[pair_ix[i : i + batch_size, 1]] + + # Compute pairwise operations for the current batch result[i : i + len(x_sample)] = pairwise_op(x_sample, y_sample) + # Use multithreading to process the batches in parallel parallel_map(par_func, np.arange(0, num_pairs, batch_size)) return result @@ -42,52 +87,181 @@ def par_func(i): def pairwise_corr(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: + """Compute the Pearson correlation coefficient for paired rows of two matrices. + + Parameters: + ---------- + x_sample : np.ndarray + A 2D array where each row represents a profile + y_sample : np.ndarray + A 2D array of the same shape as `x_sample`. + + Returns: + ------- + np.ndarray + A 1D array of Pearson correlation coefficients for each row pair in + `x_sample` and `y_sample`. """ - Compute pearson correlation between two matrices in a paired row-wise - fashion. `x_sample` and `y_sample` must be of the same shape. - """ + # Compute the mean for each row x_mean = x_sample.mean(axis=1, keepdims=True) y_mean = y_sample.mean(axis=1, keepdims=True) + # Center the rows by subtracting the mean x_center = x_sample - x_mean y_center = y_sample - y_mean + # Compute the numerator (dot product of centered vectors) numer = (x_center * y_center).sum(axis=1) + # Compute the denominator (product of vector magnitudes) denom = (x_center**2).sum(axis=1) * (y_center**2).sum(axis=1) denom = np.sqrt(denom) + # Calculate correlation coefficients corrs = numer / denom return corrs def pairwise_cosine(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: + """Compute cosine similarity for paired rows of two matrices. + + Parameters: + ---------- + x_sample : np.ndarray + A 2D array where each row represents a profile. + y_sample : np.ndarray + A 2D array of the same shape as `x_sample`. + + Returns: + ------- + np.ndarray + A 1D array of cosine similarity scores for each row pair in `x_sample` and `y_sample`. + """ + # Normalize each row to unit vectors x_norm = x_sample / np.linalg.norm(x_sample, axis=1)[:, np.newaxis] y_norm = y_sample / np.linalg.norm(y_sample, axis=1)[:, np.newaxis] + + # Compute the dot product of normalized vectors c_sim = np.sum(x_norm * y_norm, axis=1) return c_sim def pairwise_abs_cosine(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: + """Compute the absolute cosine similarity for paired rows of two matrices. + + Parameters: + ---------- + x_sample : np.ndarray + A 2D array where each row represents a profile. + y_sample : np.ndarray + A 2D array of the same shape as `x_sample`. + + Returns: + ------- + np.ndarray + Absolute values of cosine similarity scores. + """ return np.abs(pairwise_cosine(x_sample, y_sample)) def pairwise_euclidean(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: + """ + Compute the inverse Euclidean distance for paired rows of two matrices. + + Parameters: + ---------- + x_sample : np.ndarray + A 2D array where each row represents a profile. + y_sample : np.ndarray + A 2D array of the same shape as `x_sample`. + + Returns: + ------- + np.ndarray + A 1D array of inverse Euclidean distance scores (scaled to range 0-1). + """ + # Compute Euclidean distance and scale to a range of 0 to 1 e_dist = np.sqrt(np.sum((x_sample - y_sample) ** 2, axis=1)) return 1 / (1 + e_dist) def pairwise_manhattan(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: + """Compute the inverse Manhattan distance for paired rows of two matrices. + + Parameters: + ---------- + x_sample : np.ndarray + A 2D array where each row represents a profile. + y_sample : np.ndarray + A 2D array of the same shape as `x_sample`. + + Returns: + ------- + np.ndarray + A 1D array of inverse Manhattan distance scores (scaled to range 0-1). + """ m_dist = np.sum(np.abs(x_sample - y_sample), axis=1) return 1 / (1 + m_dist) def pairwise_chebyshev(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: + """Compute the inverse Chebyshev distance for paired rows of two matrices. + + Parameters: + ---------- + x_sample : np.ndarray + A 2D array where each row represents a profile. + y_sample : np.ndarray + A 2D array of the same shape as `x_sample`. + + Returns: + ------- + np.ndarray + A 1D array of inverse Chebyshev distance scores (scaled to range 0-1). + """ c_dist = np.max(np.abs(x_sample - y_sample), axis=1) return 1 / (1 + c_dist) def get_distance_fn(distance): + """ Retrieve a distance metric function based on a string identifier or custom callable. + + This function provides flexibility in specifying the distance metric to be used + for pairwise similarity or dissimilarity computations. Users can choose from a + predefined set of metrics or provide a custom callable. + + Parameters: + ---------- + distance : str or callable + The name of the distance metric or a custom callable function. Supported + string identifiers for predefined metrics are: + - "cosine": Cosine similarity. + - "abs_cosine": Absolute cosine similarity. + - "correlation": Pearson correlation coefficient. + - "euclidean": Inverse Euclidean distance (scaled to range 0-1). + - "manhattan": Inverse Manhattan distance (scaled to range 0-1). + - "chebyshev": Inverse Chebyshev distance (scaled to range 0-1). + + If a callable is provided, it must accept the paramters associated with each + callable function. + + Returns: + ------- + callable + A function implementing the specified distance metric. + + Raises: + ------- + ValueError: + If the provided `distance` is not a recognized string identifier or a valid callable. + + Example: + ------- + >>> distance_fn = get_distance_fn("cosine") + >>> similarity_scores = distance_fn(x_sample, y_sample) + """ + + # Dictionary of supported distance metrics distance_metrics = { "abs_cosine": pairwise_abs_cosine, "cosine": pairwise_cosine, @@ -97,6 +271,7 @@ def get_distance_fn(distance): "chebyshev": pairwise_chebyshev, } + # If a string is provided, look up the corresponding metric function if isinstance(distance, str): if distance not in distance_metrics: raise ValueError( @@ -104,137 +279,375 @@ def get_distance_fn(distance): ) distance_fn = distance_metrics[distance] elif callable(distance): + # If a callable is provided, use it directly distance_fn = distance else: + # Raise an error if neither a string nor a callable is provided raise ValueError("Distance must be either a string or a callable object.") + # Wrap the distance function for efficient batch processing return batch_processing(distance_fn) def random_binary_matrix(n, m, k, rng): - """Generate a random binary matrix of n*m with exactly k values in 1 per row. - Args: - n: Number of rows. - m: Number of columns. - k: Number of 1's per row. + """Generate a random binary matrix with a fixed number of 1's per row. + + This function creates an `n x m` binary matrix where each row contains exactly + `k` ones, with the positions of the ones randomized using a specified random + number generator (RNG). + + Parameters: + ---------- + n : int + Number of rows in the matrix. + m : int + Number of columns in the matrix. + k : int + Number of 1's to be placed in each row. Must satisfy `k <= m`. + rng : np.random.Generator + A NumPy random number generator instance used for shuffling the positions + of the ones in each row. Returns: - A: Random binary matrix of n*m with exactly k values in 1 per row. + ------- + np.ndarray + A binary matrix of shape `(n, m)` with exactly `k` ones per row. """ + # Initialize the binary matrix with all zeros matrix = np.zeros((n, m), dtype=int) + + # Fill the first `k` elements of each row with ones matrix[:, :k] = 1 + + # Randomly shuffle each row to distribute the ones across the columns rng.permuted(matrix, axis=1, out=matrix) + return matrix -def average_precision(rel_k) -> np.ndarray: - """Compute average precision based on binary list sorted by relevance""" +def average_precision(rel_k): + """Compute the Average Precision (AP) for a binary list of relevance scores. + + Average Precision (AP) is a performance metric for ranking tasks, which calculates + the weighted mean of precision values at the positions where relevant items occur + in a sorted list. The relevance list should be binary (1 for relevant items, 0 + for non-relevant). + + Parameters: + ---------- + rel_k : np.ndarray + A 2D binary array where each row represents a ranked list of items, and each + element indicates the relevance of the item (1 for relevant, 0 for non-relevant). + + Returns: + ------- + np.ndarray + A 1D array of Average Precision (AP) scores, one for each row in the input array. + """ + + # Cumulative sum of relevance scores along the row (True Positives at each rank) tp = np.cumsum(rel_k, axis=1) + + # Total number of relevant items (last value in cumulative sum per row) num_pos = tp[:, -1] + + # Rank positions (1-based index for each column) k = np.arange(1, rel_k.shape[1] + 1) + + # Precision at each rank pr_k = tp / k + + # Calculate AP: Weighted sum of precision values, normalized by total relevant items ap = (pr_k * rel_k).sum(axis=1) / num_pos + return ap -def ap_contiguous(rel_k_list, counts): - """Compute average precision from a list of contiguous values""" +def ap_contiguous( + rel_k_list: np.ndarray, counts: np.ndarray +) -> Tuple[np.ndarray, np.ndarray]: + """ Compute Average Precision (AP) scores from relevance labels. + + This function calculates Average Precision (AP) scores for each profile based on + relevance labels and their associated counts. It also returns configurations + indicating the number of positive and total pairs for each profile. + + Parameters: + ---------- + rel_k_list : np.ndarray + Array of relevance labels (1 for positive pairs, 0 for negative pairs), sorted + by descending similarity within profiles. + counts : np.ndarray + Array indicating how many times each profile appears in the rank list. + + Returns: + ------- + ap_scores : np.ndarray + Array of Average Precision scores for each profile. + null_confs : np.ndarray + Array of configurations, where each row corresponds to: + - Number of positive pairs (`num_pos`). + - Total number of pairs (`counts`). + """ + # Convert counts into cutoff indices to segment relevance labels cutoffs = to_cutoffs(counts) + # Calculate the number of positive pairs for each profile num_pos = np.add.reduceat(rel_k_list, cutoffs) + + # Compute the cumulative shift for handling contiguous true positives shift = np.empty_like(num_pos) shift[0], shift[1:] = 0, num_pos[:-1] + # Calculate cumulative true positives for each profile segment tp = rel_k_list.cumsum() - np.repeat(shift.cumsum(), counts) + + # Rank positions for each relevance label, adjusted by cutoff indices k = np.arange(1, len(rel_k_list) + 1) - np.repeat(cutoffs, counts) + # Compute precision at each rank (precision = TP / rank) pr_k = tp / k + + # Calculate average precision scores for each profile ap_scores = np.add.reduceat(pr_k * rel_k_list, cutoffs) / num_pos + + # Generate configurations (number of positive and total pairs) null_confs = np.stack([num_pos, counts], axis=1) + return ap_scores, null_confs -def random_ap(num_perm: int, num_pos: int, total: int, seed) -> np.ndarray: - """Compute multiple average_precision scores generated at random""" +def random_ap(num_perm, num_pos, total, seed): + """ Generate random Average Precision (AP) scores to create a null distribution. + + This function computes multiple Average Precision (AP) scores based on randomly + generated binary relevance lists. It is useful for generating a null distribution + to assess the significance of observed AP scores. + + Parameters: + ---------- + num_perm : int + Number of random permutations (i.e., how many random relevance lists to generate). + num_pos : int + Number of positive samples (1's) in each relevance list. + total : int + Total number of samples (columns) in each relevance list. + seed : int + Seed for the random number generator to ensure reproducibility. + + Returns: + ------- + np.ndarray + A 1D array containing the Average Precision scores for each randomly + generated relevance list. + """ + # Initialize the random number generator rng = np.random.default_rng(seed) + + # Generate a binary matrix with `num_perm` rows and `total` columns, + # where each row contains exactly `num_pos` ones distributed randomly rel_k = random_binary_matrix(num_perm, total, num_pos, rng) + + # Compute Average Precision (AP) scores for each row of the binary matrix null_dist = average_precision(rel_k) + return null_dist -def null_dist_cached(num_pos, total, seed, null_size, cache_dir): +def null_dist_cached( + num_pos: int, total: int, seed: int, null_size: int, cache_dir: Path +) -> np.ndarray: + """Generate or retrieve a cached null distribution for a given configuration. + + This function calculates a null distribution for a specified number of positive + pairs (`num_pos`) and total pairs (`total`). It uses caching to store and + retrieve precomputed distributions, saving time and computational resources. + + Parameters: + ---------- + num_pos : int + Number of positive pairs in the configuration. + total : int + Total number of pairs (positive + negative) in the configuration. + seed : int + Random seed for reproducibility. + null_size : int + Number of samples to generate in the null distribution. + cache_dir : Path + Directory to store or retrieve cached null distributions. + + Returns: + ------- + np.ndarray + Null distribution for the specified configuration. + """ + # Check if a seed is provided to enable caching if seed is not None: + # Define the cache file name based on the configuration cache_file = cache_dir / f"n{total}_k{num_pos}.npy" + + # If the cache file exists, load the null distribution from it if cache_file.is_file(): null_dist = np.load(cache_file) else: + # If the cache file doesn't exist, compute the null distribution null_dist = random_ap(null_size, num_pos, total, seed) + + # Save the computed distribution to the cache np.save(cache_file, null_dist) else: + # If no seed is provided, compute the null distribution without caching null_dist = random_ap(null_size, num_pos, total, seed) + + # Return the null distribution (loaded or computed) return null_dist -def get_null_dists(confs, null_size, seed): +def get_null_dists(confs: np.ndarray, null_size: int, seed: int) -> np.ndarray: + """Generate null distributions for each configuration of positive and total pairs. + Parameters: + ---------- + confs : np.ndarray + Array where each row contains the number of positive pairs (`num_pos`) + and total pairs (`total`) for a specific configuration. + null_size : int + Number of samples to generate in the null distribution. + seed : int + Random seed for reproducibility. + + Returns: + ------- + np.ndarray + A 2D array where each row corresponds to a null distribution for a specific + configuration. + """ + # Define the directory for caching null distributions cache_dir = Path.home() / ".copairs" / f"seed{seed}" / f"ns{null_size}" cache_dir.mkdir(parents=True, exist_ok=True) + + # Number of configurations and random seeds for each configuration num_confs = len(confs) rng = np.random.default_rng(seed) seeds = rng.integers(8096, size=num_confs) + # Initialize an array to store null distributions null_dists = np.empty([len(confs), null_size], dtype=np.float32) + # Function to generate null distributions for each configuration def par_func(i): num_pos, total = confs[i] null_dists[i] = null_dist_cached(num_pos, total, seeds[i], null_size, cache_dir) + # Parallelize the generation of null distributions parallel_map(par_func, np.arange(num_confs)) + return null_dists def p_values(ap_scores: np.ndarray, null_confs: np.ndarray, null_size: int, seed: int): - """Calculate p values for an array of ap_scores and null configurations. It uses the path - folder to cache null calculations. + """Calculate p-values for an array of Average Precision (AP) scores + using a null distribution. - Parameters + Parameters: ---------- ap_scores : np.ndarray - Ap scores for which to calculate p value. + Array of observed AP scores for which to calculate p-values. null_confs : np.ndarray - Number of average precisions calculated. It serves as an indicator of - how relevant is the resultant score. + Configuration array indicating the relevance or context of each AP score. Used + to generate corresponding null distributions. null_size : int + Number of samples to generate in the null distribution for each configuration. seed : int - Random initializing value. - - Examples - -------- - FIXME: Add docs. - + Seed for the random number generator to ensure reproducibility of the null + distribution. + Returns: + ------- + np.ndarray + An array of p-values corresponding to the input AP scores. """ + # Identify unique configurations and their indices confs, rev_ix = np.unique(null_confs, axis=0, return_inverse=True) + + # Generate null distributions for each unique configuration null_dists = get_null_dists(confs, null_size, seed) + + # Sort null distributions for efficient p-value computation null_dists.sort(axis=1) + + # Initialize an array to store the p-values pvals = np.empty(len(ap_scores), dtype=np.float32) + + # Compute p-values for each AP score for i, (ap_score, ix) in enumerate(zip(ap_scores, rev_ix)): - # Reverse to get from hi to low + # Find the rank of the observed AP score in the sorted null distribution num = null_size - np.searchsorted(null_dists[ix], ap_score) + + # Calculate the p-value as the proportion of null scores >= observed score pvals[i] = (num + 1) / (null_size + 1) + return pvals -def concat_ranges(start: np.ndarray, end: np.ndarray) -> np.ndarray: - """Create a 1-d array concatenating multiple ranges""" +def concat_ranges(start, end): + """ Create a 1D array by concatenating multiple integer ranges. + + This function generates a single concatenated array from multiple ranges defined + by the `start` and `end` arrays. Each range is inclusive of `start` and exclusive + of `end`. + + Parameters: + ---------- + start : np.ndarray + A 1D array of start indices for the ranges. + end : np.ndarray + A 1D array of end indices for the ranges. Must have the same shape as `start`. + + Returns: + ------- + np.ndarray + A 1D array containing the concatenated ranges. + """ + # Generate individual ranges using `range` for each pair of start and end slices = map(range, start, end) + + # Flatten the ranges into a single iterable slices = itertools.chain.from_iterable(slices) + + # Calculate the total length of the concatenated ranges count = (end - start).sum() + + # Create a 1D array from the concatenated ranges mask = np.fromiter(slices, dtype=np.int32, count=count) + return mask -def to_cutoffs(counts: np.ndarray): - """Convert a list of counts into cutoff indices.""" +def to_cutoffs(counts: np.ndarray) -> np.ndarray: + """Convert counts into cumulative cutoff indices. + + This function generates a 1D array of indices that mark the start of each segment + in a cumulative list. The first index is always `0`, and subsequent indices + correspond to the cumulative sum of counts up to the previous entry. + + Parameters: + ---------- + counts : np.ndarray + A 1D array of counts representing the size of each segment. + + Returns: + ------- + np.ndarray + A 1D array of cutoff indices where each value indicates the starting index + for the corresponding segment. + """ + # Initialize an empty array for cutoff indices cutoffs = np.empty_like(counts) - cutoffs[0], cutoffs[1:] = 0, counts.cumsum()[:-1] + + # Set the first cutoff to 0 (start of the first segment) + cutoffs[0] = 0 + + # Compute subsequent cutoffs using cumulative sums, excluding the last element + cutoffs[1:] = counts.cumsum()[:-1] + return cutoffs diff --git a/src/copairs/map/average_precision.py b/src/copairs/map/average_precision.py index 10b481a..b055d81 100644 --- a/src/copairs/map/average_precision.py +++ b/src/copairs/map/average_precision.py @@ -12,92 +12,272 @@ logger = logging.getLogger("copairs") -def build_rank_lists(pos_pairs, neg_pairs, pos_sims, neg_sims): +def build_rank_lists( + pos_pairs: np.ndarray, + neg_pairs: np.ndarray, + pos_sims: np.ndarray, + neg_sims: np.ndarray, +): + """Build rank lists for calculating average precision. + + This function processes positive and negative pairs along with their similarity scores + to construct rank lists and determine unique profile indices with their associated counts. + + Parameters: + ---------- + pos_pairs : np.ndarray + Array of positive pair indices, where each pair is represented as a pair of integers. + + neg_pairs : np.ndarray + Array of negative pair indices, where each pair is represented as a pair of integers. + + pos_sims : np.ndarray + Array of similarity scores for positive pairs. + + neg_sims : np.ndarray + Array of similarity scores for negative pairs. + + Returns: + ------- + paired_ix : np.ndarray + Unique indices of profiles that appear in the rank lists. + + rel_k_list : np.ndarray + Array of relevance labels (1 for positive pairs, 0 for negative pairs) sorted by + decreasing similarity within each profile. + + counts : np.ndarray + Array of counts indicating how many times each profile index appears in the rank lists. + """ + + # Combine relevance labels: 1 for positive pairs, 0 for negative pairs labels = np.concatenate( [ - np.ones(pos_pairs.size, dtype=np.int32), - np.zeros(neg_pairs.size, dtype=np.int32), + np.ones(pos_pairs.size, dtype=np.int32), # Label positive pairs + np.zeros(neg_pairs.size, dtype=np.int32), # Label negative pairs ] ) + + # Flatten positive and negative pair indices for ranking ix = np.concatenate([pos_pairs.ravel(), neg_pairs.ravel()]) + + # Expand similarity scores to match the flattened pair indices sim_all = np.concatenate([np.repeat(pos_sims, 2), np.repeat(neg_sims, 2)]) + + # Sort by similarity (descending) and then by index (lexicographical order) + # `1 - sim_all` ensures higher similarity values appear first, prioritizing + # pairs with stronger similarity scores for ranking. + # `ix` acts as a secondary criterion, ensuring consistent ordering of pairs + # with equal similarity scores by their indices (lexicographical order). ix_sort = np.lexsort([1 - sim_all, ix]) + + # Create the rank list of relevance labels sorted by similarity and index rel_k_list = labels[ix_sort] + + # Find unique profile indices and count their occurrences in the pairs paired_ix, counts = np.unique(ix, return_counts=True) + return paired_ix, rel_k_list, counts def average_precision( - meta, - feats, - pos_sameby, - pos_diffby, - neg_sameby, - neg_diffby, - batch_size=20000, - distance="cosine", + meta: pd.DataFrame, + feats: pd.DataFrame, + pos_sameby: list[str], + pos_diffby: list[str], + neg_sameby: list[str], + neg_diffby: list[str], + batch_size: int = 20000, + distance: str = "cosine", ) -> pd.DataFrame: + """Calculate average precision (AP) scores for pairs of profiles based on their + similarity. + + This function identifies positive and negative pairs of profiles using metadata + rules, computes their similarity scores, and calculates average precision + scores for each profile. The results include the number of positive and total pairs + for each profile. + + Parameters: + ---------- + meta : pd.DataFrame + Metadata of the profiles, including columns used for defining pairs. + This DataFrame should include the columns specified in `pos_sameby`, + `pos_diffby`, `neg_sameby`, and `neg_diffby`. + + feats : np.ndarray + Feature matrix representing the profiles, where rows correspond to profiles + and columns to features. + + pos_sameby : list + Metadata columns used to define positive pairs. Two profiles are considered a + positive pair if they belong to the same group that is not a control group. + For example, replicate profiles of the same compound are positive pairs and + should share the same value in a column identifying compounds. + + pos_diffby : list + Metadata columns used to differentiate positive pairs. Positive pairs do not need + to differ in any metadata columns, so this is typically left empty. However, + if necessary (e.g., to account for batch effects), you can specify columns + such as batch identifiers. + + neg_sameby : list + Metadata columns used to define negative pairs. Typically left empty, as profiles + forming a negative pair (e.g., a compound and a DMSO/control) do not need to + share any metadata values. This ensures comparisons are made without enforcing + unnecessary constraints. + + neg_diffby : list + Metadata columns used to differentiate negative pairs. Two profiles are considered + a negative pair if one belongs to a compound group and the other to a DMSO/ + control group. They must differ in specified metadata columns, such as those + identifying the compound and the treatment index, to ensure comparisons are + only made between compounds and DMSO controls (not between different compounds). + + batch_size : int + The batch size for similarity computations to optimize memory usage. + Default is 20000. + + distance : str + The distance metric used for computing similarities. Default is "cosine". + + Returns: + ------- + pd.DataFrame + A DataFrame containing the following columns: + - 'average_precision': The calculated average precision score for each profile. + - 'n_pos_pairs': The number of positive pairs for each profile. + - 'n_total_pairs': The total number of pairs for each profile. + - Additional metadata columns from the input. + + Raises: + ------ + UnpairedException + If no positive or negative pairs are found in the dataset. + + Notes: + ------ + - Positive Pair Rules: + * Positive pairs are defined by `pos_sameby` (profiles share these metadata values) + and optionally differentiated by `pos_diffby` (profiles must differ in these metadata values if specified). + - Negative Pair Rules: + * Negative pairs are defined by `neg_diffby` (profiles differ in these metadata values) + and optionally constrained by `neg_sameby` (profiles share these metadata values if specified). + """ + + # Combine all metadata columns needed for pair definitions columns = flatten_str_list(pos_sameby, pos_diffby, neg_sameby, neg_diffby) + + # Validate and filter metadata to ensure the required columns are present and usable meta, columns = evaluate_and_filter(meta, columns) validate_pipeline_input(meta, feats, columns) + + # Get the distance function for similarity calculations (e.g., cosine) distance_fn = compute.get_distance_fn(distance) - # Critical!, otherwise the indexing wont work + # Reset metadata index for consistent indexing meta = meta.reset_index(drop=True).copy() + + # Initialize the Matcher object to find pairs based on metadata rules logger.info("Indexing metadata...") matcher = Matcher(meta, columns, seed=0) + # Identify positive pairs based on `pos_sameby` and `pos_diffby` logger.info("Finding positive pairs...") pos_pairs = matcher.get_all_pairs(sameby=pos_sameby, diffby=pos_diffby) pos_total = sum(len(p) for p in pos_pairs.values()) if pos_total == 0: raise UnpairedException("Unable to find positive pairs.") + + # Convert positive pairs to a NumPy array for efficient computation pos_pairs = np.fromiter( itertools.chain.from_iterable(pos_pairs.values()), dtype=np.dtype((np.int32, 2)), count=pos_total, ) + # Identify negative pairs based on `neg_sameby` and `neg_diffby` logger.info("Finding negative pairs...") neg_pairs = matcher.get_all_pairs(sameby=neg_sameby, diffby=neg_diffby) neg_total = sum(len(p) for p in neg_pairs.values()) if neg_total == 0: raise UnpairedException("Unable to find negative pairs.") + + # Convert negative pairs to a NumPy array for efficient computation neg_pairs = np.fromiter( itertools.chain.from_iterable(neg_pairs.values()), dtype=np.dtype((np.int32, 2)), count=neg_total, ) + # Compute similarities for positive pairs logger.info("Computing positive similarities...") pos_sims = distance_fn(feats, pos_pairs, batch_size) + # Compute similarities for negative pairs logger.info("Computing negative similarities...") neg_sims = distance_fn(feats, neg_pairs, batch_size) + # Build rank lists for calculating average precision logger.info("Building rank lists...") paired_ix, rel_k_list, counts = build_rank_lists( pos_pairs, neg_pairs, pos_sims, neg_sims ) + # Compute average precision scores and associated configurations logger.info("Computing average precision...") ap_scores, null_confs = compute.ap_contiguous(rel_k_list, counts) + # Add AP scores and pair counts to the metadata DataFrame logger.info("Creating result DataFrame...") meta["n_pos_pairs"] = 0 meta["n_total_pairs"] = 0 meta.loc[paired_ix, "average_precision"] = ap_scores meta.loc[paired_ix, "n_pos_pairs"] = null_confs[:, 0] meta.loc[paired_ix, "n_total_pairs"] = null_confs[:, 1] + logger.info("Finished.") return meta -def p_values(dframe: pd.DataFrame, null_size: int, seed: int): - """Compute p-values""" +def p_values(dframe: pd.DataFrame, null_size: int, seed: int) -> np.ndarray: + """Compute p-values for average precision scores based on a null distribution. + + This function calculates the p-values for each profile in the input DataFrame, + comparing their average precision scores (`average_precision`) against a null + distribution generated for their specific configurations (number of positive + and total pairs). Profiles with no positive pairs are excluded from the p-value calculation. + + Parameters + ---------- + dframe : pd.DataFrame + A DataFrame containing the following columns: + - `average_precision`: The AP scores for each profile. + - `n_pos_pairs`: Number of positive pairs for each profile. + - `n_total_pairs`: Total number of pairs (positive + negative) for each profile. + null_size : int + The number of samples to generate in the null distribution for significance testing. + seed : int + Random seed for reproducibility of the null distribution. + + Returns + ------- + np.ndarray + An array of p-values for each profile in the DataFrame. Profiles with no positive + pairs will have NaN as their p-value. + """ + # Create a mask to filter profiles with at least one positive pair mask = dframe["n_pos_pairs"] > 0 + + # Initialize the p-values array with NaN for all profiles pvals = np.full(len(dframe), np.nan, dtype=np.float32) + + # Extract the average precision scores and null configurations for valid profiles scores = dframe.loc[mask, "average_precision"].values null_confs = dframe.loc[mask, ["n_pos_pairs", "n_total_pairs"]].values + + # Compute p-values for profiles with valid configurations using the null distribution pvals[mask] = compute.p_values(scores, null_confs, null_size, seed) + + # Return the array of p-values, including NaN for invalid profiles return pvals diff --git a/src/copairs/map/filter.py b/src/copairs/map/filter.py index c2956da..1ab4129 100644 --- a/src/copairs/map/filter.py +++ b/src/copairs/map/filter.py @@ -6,13 +6,38 @@ import pandas as pd -def validate_pipeline_input(meta, feats, columns): +def validate_pipeline_input( + meta: pd.DataFrame, feats: np.ndarray, columns: List[str] +) -> None: + """ Validate the metadata and features for consistency and completeness. + + Parameters: + ---------- + meta : pd.DataFrame + The metadata DataFrame describing the profiles. + feats : np.ndarray + The feature matrix where rows correspond to profiles in the metadata. + columns : List[str] + List of column names in the metadata to validate for null values. + + Raises: + ------- + ValueError: + - If any of the specified metadata columns contain null values. + - If the number of rows in the metadata and features are not equal. + - If the feature matrix contains null values. + """ + # Check for null values in the specified metadata columns if meta[columns].isna().any(axis=None): - raise ValueError("metadata columns should not have null values.") + raise ValueError("Metadata columns should not contain null values.") + + # Check if the number of rows in metadata matches the feature matrix if len(meta) != len(feats): - raise ValueError("meta and feats have different number of rows") + raise ValueError("Metadata and features must have the same number of rows.") + + # Check for null values in the feature matrix if np.isnan(feats).any(): - raise ValueError("features should not have null values.") + raise ValueError("Features should not contain null values.") def flatten_str_list(*args): @@ -29,50 +54,139 @@ def flatten_str_list(*args): return columns -def evaluate_and_filter(df, columns) -> Tuple[pd.DataFrame, List[str]]: - """Evaluate queries and filter the dataframe""" +def evaluate_and_filter( + df: pd.DataFrame, columns: List[str] +) -> Tuple[pd.DataFrame, List[str]]: + """ Evaluate query filters and filter the metadata DataFrame based on specified columns. + + This function processes column specifications, extracts any filter conditions, + applies these conditions to the metadata DataFrame, and returns the filtered metadata + along with the updated list of columns. + + Parameters: + ---------- + df : pd.DataFrame + The metadata DataFrame containing information about profiles to be filtered. + columns : List[str] + A list of metadata column names. + + Returns: + ------- + Tuple[pd.DataFrame, List[str]] + - The filtered metadata DataFrame. + - The updated list of columns after processing any filter specifications. + """ + # Extract query filters from the column specifications query_list, columns = extract_filters(columns, df.columns) + + # Apply the extracted filters to the metadata DataFrame df = apply_filters(df, query_list) + + # Return the filtered metadata DataFrame and the updated list of columns return df, columns -def extract_filters(columns, df_columns) -> Tuple[List[str], List[str]]: - """Extract and validate filters from columns""" +def extract_filters( + columns: List[str], df_columns: List[str] +) -> Tuple[List[str], List[str]]: + """ Extract and validate query filters from selected metadata columns. + + Parameters: + ---------- + columns : List[str] + A list of selected metadata column names or query expressions. Query expressions + should follow a valid syntax (e.g., "metadata_column > 5" or "metadata_column == 'value'"). + df_columns : List[str] + All available metadata column names to validate against. + + Returns: + ------- + Tuple[List[str], List[str]] + - `queries_to_eval`: A list of valid query expressions to evaluate. + - `parsed_cols`: A list of valid metadata column names extracted from the input `columns`. + + Raises: + ------- + ValueError: + - If a metadata column or query expression is invalid (e.g., references a non-existent column). + - If duplicate queries are found for the same metadata column. + """ + # Initialize lists to store parsed metadata column names and query expressions parsed_cols = [] queries_to_eval = [] + # Iterate through each entry in the selected metadata columns for col in columns: if col in df_columns: + # If the entry is a valid metadata column name, add it to parsed_cols parsed_cols.append(col) continue + + # Use regex to extract metadata column names from query expressions column_names = re.findall(r"(\w+)\s*[=<>!]+", col) + # Validate the extracted metadata column names against all available metadata columns valid_column_names = [col for col in column_names if col in df_columns] if not valid_column_names: - raise ValueError(f"Invalid query or column name: {col}") + raise ValueError(f"Invalid query or metadata column name: {col}") + # Add valid query expressions and associated metadata columns queries_to_eval.append(col) parsed_cols.extend(valid_column_names) + # Check for duplicate metadata columns in the parsed list if len(parsed_cols) != len(set(parsed_cols)): - raise ValueError(f"Duplicate queries for column: {col}") + raise ValueError(f"Duplicate queries for metadata column: {col}") + # Return the queries to evaluate and the parsed metadata column names return queries_to_eval, parsed_cols -def apply_filters(df, query_list): - """Combine and apply filters to dataframe""" +def apply_filters(df: pd.DataFrame, query_list: List[str]) -> pd.DataFrame: + """ Combine and apply query filters to a DataFrame. + + This function takes a list of query expressions and applies them to a DataFrame + to filter its rows. If no query expressions are provided, the original DataFrame + is returned unchanged. + + Parameters: + ---------- + df : pd.DataFrame + The DataFrame to which the filters will be applied. + query_list : List[str] + A list of query expressions (e.g., "column_name > 5"). These expressions + should follow the syntax supported by `pd.DataFrame.query`. + + Returns: + ------- + pd.DataFrame + The DataFrame filtered based on the provided query expressions. + + Raises: + ------- + ValueError: + - If the combined query results in an empty DataFrame. + - If the combined query expression is invalid. + """ + # If no queries are provided, return the original DataFrame unchanged if not query_list: return df + # Combine the query expressions into a single string using logical AND (&) combined_query = " & ".join(f"({query})" for query in query_list) + try: + # Apply the combined query to filter the DataFrame df_filtered = df.query(combined_query) + + # Raise an error if the filtered DataFrame is empty if df_filtered.empty: raise ValueError(f"No data matched the query: {combined_query}") except Exception as e: + # Handle any issues with the query expression and provide feedback raise ValueError( f"Invalid combined query expression: {combined_query}. Error: {e}" ) + # Return the filtered DataFrame return df_filtered diff --git a/src/copairs/map/map.py b/src/copairs/map/map.py index 2e354cc..563897d 100644 --- a/src/copairs/map/map.py +++ b/src/copairs/map/map.py @@ -13,24 +13,61 @@ def mean_average_precision( ap_scores: pd.DataFrame, sameby, null_size: int, threshold: float, seed: int ) -> pd.DataFrame: + """ Calculate the Mean Average Precision (mAP) score and associated p-values. + + This function computes the Mean Average Precision (mAP) score by grouping profiles + based on the specified criteria (`sameby`). It calculates the significance of mAP + scores by comparing them to a null distribution and performs multiple testing + corrections. + + Parameters: + ---------- + ap_scores : pd.DataFrame + DataFrame containing individual Average Precision (AP) scores and pair statistics + (e.g., number of positive pairs `n_pos_pairs` and total pairs `n_total_pairs`). + sameby : list or str + Metadata column(s) used to group profiles for mAP calculation. + null_size : int + Number of samples in the null distribution for significance testing. + threshold : float + p-value threshold for identifying significant MaP scores. + seed : int + Random seed for reproducibility. + + Returns: + ------- + pd.DataFrame + DataFrame with the following columns: + - `mean_average_precision`: Mean AP score for each group. + - `p_value`: p-value comparing mAP to the null distribution. + - `corrected_p_value`: Adjusted p-value after multiple testing correction. + - `below_p`: Boolean indicating if the p-value is below the threshold. + - `below_corrected_p`: Boolean indicating if the corrected p-value is below the threshold. + """ + # Filter out invalid or incomplete AP scores ap_scores = ap_scores.query("~average_precision.isna() and n_pos_pairs > 0") ap_scores = ap_scores.reset_index(drop=True).copy() logger.info("Computing null_dist...") + # Extract configurations for null distribution generation null_confs = ap_scores[["n_pos_pairs", "n_total_pairs"]].values null_confs, rev_ix = np.unique(null_confs, axis=0, return_inverse=True) + + # Generate null distributions for each unique configuration null_dists = compute.get_null_dists(null_confs, null_size, seed=seed) ap_scores["null_ix"] = rev_ix + # Function to calculate the p-value for a mAP score based on the null distribution def get_p_value(params): map_score, indices = params null_dist = null_dists[rev_ix[indices]].mean(axis=0) num = (null_dist > map_score).sum() - p_value = (num + 1) / (null_size + 1) + p_value = (num + 1) / (null_size + 1) # Add 1 for stability return p_value logger.info("Computing p-values...") + # Group by the specified metadata column(s) and calculate mean AP map_scores = ap_scores.groupby(sameby, observed=True).agg( { "average_precision": ["mean", lambda x: list(x.index)], @@ -38,14 +75,20 @@ def get_p_value(params): ) map_scores.columns = ["mean_average_precision", "indices"] + # Compute p-values for each group using the null distributions params = map_scores[["mean_average_precision", "indices"]] map_scores["p_value"] = thread_map(get_p_value, params.values, leave=False) + + # Perform multiple testing correction on p-values reject, pvals_corrected, alphacSidak, alphacBonf = multipletests( map_scores["p_value"], method="fdr_bh" ) map_scores["corrected_p_value"] = pvals_corrected + + # Mark scores below the p-value threshold map_scores["below_p"] = map_scores["p_value"] < threshold map_scores["below_corrected_p"] = map_scores["corrected_p_value"] < threshold - map_scores.drop(columns=["indices"], inplace=True) - map_scores.reset_index(inplace=True) - return map_scores + + + + return map_scores \ No newline at end of file From 68ddeb8e703149aa7ca84832aacc0c9794e4ac78 Mon Sep 17 00:00:00 2001 From: axiomcura Date: Mon, 16 Dec 2024 11:55:44 -0700 Subject: [PATCH 02/21] executed ruff --- src/copairs/compute.py | 12 ++++++------ src/copairs/map/filter.py | 14 +++++++------- src/copairs/map/map.py | 6 ++---- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/copairs/compute.py b/src/copairs/compute.py index 141d517..e188049 100644 --- a/src/copairs/compute.py +++ b/src/copairs/compute.py @@ -224,7 +224,7 @@ def pairwise_chebyshev(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray def get_distance_fn(distance): - """ Retrieve a distance metric function based on a string identifier or custom callable. + """Retrieve a distance metric function based on a string identifier or custom callable. This function provides flexibility in specifying the distance metric to be used for pairwise similarity or dissimilarity computations. Users can choose from a @@ -242,8 +242,8 @@ def get_distance_fn(distance): - "manhattan": Inverse Manhattan distance (scaled to range 0-1). - "chebyshev": Inverse Chebyshev distance (scaled to range 0-1). - If a callable is provided, it must accept the paramters associated with each - callable function. + If a callable is provided, it must accept the paramters associated with each + callable function. Returns: ------- @@ -366,7 +366,7 @@ def average_precision(rel_k): def ap_contiguous( rel_k_list: np.ndarray, counts: np.ndarray ) -> Tuple[np.ndarray, np.ndarray]: - """ Compute Average Precision (AP) scores from relevance labels. + """Compute Average Precision (AP) scores from relevance labels. This function calculates Average Precision (AP) scores for each profile based on relevance labels and their associated counts. It also returns configurations @@ -418,7 +418,7 @@ def ap_contiguous( def random_ap(num_perm, num_pos, total, seed): - """ Generate random Average Precision (AP) scores to create a null distribution. + """Generate random Average Precision (AP) scores to create a null distribution. This function computes multiple Average Precision (AP) scores based on randomly generated binary relevance lists. It is useful for generating a null distribution @@ -590,7 +590,7 @@ def p_values(ap_scores: np.ndarray, null_confs: np.ndarray, null_size: int, seed def concat_ranges(start, end): - """ Create a 1D array by concatenating multiple integer ranges. + """Create a 1D array by concatenating multiple integer ranges. This function generates a single concatenated array from multiple ranges defined by the `start` and `end` arrays. Each range is inclusive of `start` and exclusive diff --git a/src/copairs/map/filter.py b/src/copairs/map/filter.py index 1ab4129..0cbec43 100644 --- a/src/copairs/map/filter.py +++ b/src/copairs/map/filter.py @@ -9,7 +9,7 @@ def validate_pipeline_input( meta: pd.DataFrame, feats: np.ndarray, columns: List[str] ) -> None: - """ Validate the metadata and features for consistency and completeness. + """Validate the metadata and features for consistency and completeness. Parameters: ---------- @@ -57,7 +57,7 @@ def flatten_str_list(*args): def evaluate_and_filter( df: pd.DataFrame, columns: List[str] ) -> Tuple[pd.DataFrame, List[str]]: - """ Evaluate query filters and filter the metadata DataFrame based on specified columns. + """Evaluate query filters and filter the metadata DataFrame based on specified columns. This function processes column specifications, extracts any filter conditions, applies these conditions to the metadata DataFrame, and returns the filtered metadata @@ -89,7 +89,7 @@ def evaluate_and_filter( def extract_filters( columns: List[str], df_columns: List[str] ) -> Tuple[List[str], List[str]]: - """ Extract and validate query filters from selected metadata columns. + """Extract and validate query filters from selected metadata columns. Parameters: ---------- @@ -143,10 +143,10 @@ def extract_filters( def apply_filters(df: pd.DataFrame, query_list: List[str]) -> pd.DataFrame: - """ Combine and apply query filters to a DataFrame. + """Combine and apply query filters to a DataFrame. - This function takes a list of query expressions and applies them to a DataFrame - to filter its rows. If no query expressions are provided, the original DataFrame + This function takes a list of query expressions and applies them to a DataFrame + to filter its rows. If no query expressions are provided, the original DataFrame is returned unchanged. Parameters: @@ -154,7 +154,7 @@ def apply_filters(df: pd.DataFrame, query_list: List[str]) -> pd.DataFrame: df : pd.DataFrame The DataFrame to which the filters will be applied. query_list : List[str] - A list of query expressions (e.g., "column_name > 5"). These expressions + A list of query expressions (e.g., "column_name > 5"). These expressions should follow the syntax supported by `pd.DataFrame.query`. Returns: diff --git a/src/copairs/map/map.py b/src/copairs/map/map.py index 563897d..7e16e62 100644 --- a/src/copairs/map/map.py +++ b/src/copairs/map/map.py @@ -13,7 +13,7 @@ def mean_average_precision( ap_scores: pd.DataFrame, sameby, null_size: int, threshold: float, seed: int ) -> pd.DataFrame: - """ Calculate the Mean Average Precision (mAP) score and associated p-values. + """Calculate the Mean Average Precision (mAP) score and associated p-values. This function computes the Mean Average Precision (mAP) score by grouping profiles based on the specified criteria (`sameby`). It calculates the significance of mAP @@ -89,6 +89,4 @@ def get_p_value(params): map_scores["below_p"] = map_scores["p_value"] < threshold map_scores["below_corrected_p"] = map_scores["corrected_p_value"] < threshold - - - return map_scores \ No newline at end of file + return map_scores From 73cc0fb09d3acba341ad86cae272155cea0b30b2 Mon Sep 17 00:00:00 2001 From: axiomcura Date: Wed, 18 Dec 2024 09:46:36 -0700 Subject: [PATCH 03/21] updated docstrings and type hinting in compute module --- src/copairs/compute.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/copairs/compute.py b/src/copairs/compute.py index e188049..6986e58 100644 --- a/src/copairs/compute.py +++ b/src/copairs/compute.py @@ -2,7 +2,7 @@ import os from multiprocessing.pool import ThreadPool from pathlib import Path -from typing import Callable, Tuple +from typing import Callable, Tuple, Optional, Union import numpy as np from tqdm.autonotebook import tqdm @@ -223,7 +223,7 @@ def pairwise_chebyshev(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray return 1 / (1 + c_dist) -def get_distance_fn(distance): +def get_distance_fn(distance: Union[str, Callable]) -> Callable: """Retrieve a distance metric function based on a string identifier or custom callable. This function provides flexibility in specifying the distance metric to be used @@ -289,7 +289,9 @@ def get_distance_fn(distance): return batch_processing(distance_fn) -def random_binary_matrix(n, m, k, rng): +def random_binary_matrix( + n: int, m: int, k: int, rng: Optional[np.random.Generator] +) -> np.ndarray: """Generate a random binary matrix with a fixed number of 1's per row. This function creates an `n x m` binary matrix where each row contains exactly @@ -304,9 +306,10 @@ def random_binary_matrix(n, m, k, rng): Number of columns in the matrix. k : int Number of 1's to be placed in each row. Must satisfy `k <= m`. - rng : np.random.Generator + rng : Optional[np.random.Generator] A NumPy random number generator instance used for shuffling the positions - of the ones in each row. + of the ones in each row. If None, a new Generator will be created using + the default random seed. Returns: ------- @@ -325,7 +328,7 @@ def random_binary_matrix(n, m, k, rng): return matrix -def average_precision(rel_k): +def average_precision(rel_k: np.ndarray) -> np.ndarray: """Compute the Average Precision (AP) for a binary list of relevance scores. Average Precision (AP) is a performance metric for ranking tasks, which calculates @@ -417,7 +420,7 @@ def ap_contiguous( return ap_scores, null_confs -def random_ap(num_perm, num_pos, total, seed): +def random_ap(num_perm: int, num_pos: int, total: int, seed: int): """Generate random Average Precision (AP) scores to create a null distribution. This function computes multiple Average Precision (AP) scores based on randomly @@ -589,7 +592,7 @@ def p_values(ap_scores: np.ndarray, null_confs: np.ndarray, null_size: int, seed return pvals -def concat_ranges(start, end): +def concat_ranges(start: np.ndarray, end: np.ndarray) -> np.ndarray: """Create a 1D array by concatenating multiple integer ranges. This function generates a single concatenated array from multiple ranges defined From dc8515a0f9877af6c70526105b963bb1a756d85d Mon Sep 17 00:00:00 2001 From: axiomcura Date: Wed, 18 Dec 2024 09:48:26 -0700 Subject: [PATCH 04/21] updated type hinting for 3.8 support --- src/copairs/map/average_precision.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/copairs/map/average_precision.py b/src/copairs/map/average_precision.py index b055d81..1f63f3c 100644 --- a/src/copairs/map/average_precision.py +++ b/src/copairs/map/average_precision.py @@ -3,6 +3,7 @@ import numpy as np import pandas as pd +from typing import List from copairs import compute from copairs.matching import Matcher, UnpairedException @@ -83,10 +84,10 @@ def build_rank_lists( def average_precision( meta: pd.DataFrame, feats: pd.DataFrame, - pos_sameby: list[str], - pos_diffby: list[str], - neg_sameby: list[str], - neg_diffby: list[str], + pos_sameby: List[str], + pos_diffby: List[str], + neg_sameby: List[str], + neg_diffby: List[str], batch_size: int = 20000, distance: str = "cosine", ) -> pd.DataFrame: From f9115a036fa132d1a4a2ae3dfe9628ed1f1d6ed5 Mon Sep 17 00:00:00 2001 From: axiomcura Date: Wed, 18 Dec 2024 13:17:49 -0700 Subject: [PATCH 05/21] updated error message --- src/copairs/map/filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/copairs/map/filter.py b/src/copairs/map/filter.py index 0cbec43..6c7d71c 100644 --- a/src/copairs/map/filter.py +++ b/src/copairs/map/filter.py @@ -37,7 +37,7 @@ def validate_pipeline_input( # Check for null values in the feature matrix if np.isnan(feats).any(): - raise ValueError("Features should not contain null values.") + raise ValueError("features should not have null values.") def flatten_str_list(*args): From 6d68eee1e3fee95ad895876383b2138b9221e44b Mon Sep 17 00:00:00 2001 From: axiomcura Date: Wed, 18 Dec 2024 13:33:40 -0700 Subject: [PATCH 06/21] updated error messages --- src/copairs/map/filter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/copairs/map/filter.py b/src/copairs/map/filter.py index 6c7d71c..c9603be 100644 --- a/src/copairs/map/filter.py +++ b/src/copairs/map/filter.py @@ -29,7 +29,7 @@ def validate_pipeline_input( """ # Check for null values in the specified metadata columns if meta[columns].isna().any(axis=None): - raise ValueError("Metadata columns should not contain null values.") + raise ValueError("metadata columns should not have null values.") # Check if the number of rows in metadata matches the feature matrix if len(meta) != len(feats): @@ -136,7 +136,7 @@ def extract_filters( # Check for duplicate metadata columns in the parsed list if len(parsed_cols) != len(set(parsed_cols)): - raise ValueError(f"Duplicate queries for metadata column: {col}") + raise ValueError(f"Duplicate queries for column: {col}") # Return the queries to evaluate and the parsed metadata column names return queries_to_eval, parsed_cols From f7a94360c15ea9bc1ddfed26dc5d718a7f4168f7 Mon Sep 17 00:00:00 2001 From: Shantanu Singh Date: Fri, 3 Jan 2025 13:06:05 -0500 Subject: [PATCH 07/21] chore: update license year to 2025 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 74cb62b..77876bc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2024, Broad Institute +Copyright (c) 2025, Broad Institute Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: From eb1e5e23b5e50b6a7cfa5722252fc6ff7bae4dda Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Thu, 30 Jan 2025 01:04:58 -0500 Subject: [PATCH 08/21] feat(map): add num workers as param --- src/copairs/map/map.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/copairs/map/map.py b/src/copairs/map/map.py index 7e16e62..1ff7684 100644 --- a/src/copairs/map/map.py +++ b/src/copairs/map/map.py @@ -11,7 +11,7 @@ def mean_average_precision( - ap_scores: pd.DataFrame, sameby, null_size: int, threshold: float, seed: int + ap_scores: pd.DataFrame, sameby, null_size: int, threshold: float, seed: int, max_workers: int = 32 ) -> pd.DataFrame: """Calculate the Mean Average Precision (mAP) score and associated p-values. @@ -77,7 +77,7 @@ def get_p_value(params): # Compute p-values for each group using the null distributions params = map_scores[["mean_average_precision", "indices"]] - map_scores["p_value"] = thread_map(get_p_value, params.values, leave=False) + map_scores["p_value"] = thread_map(get_p_value, params.values, leave=False, max_workers=max_workers) # Perform multiple testing correction on p-values reject, pvals_corrected, alphacSidak, alphacBonf = multipletests( From d3cba88f334ba261d04dc8fe9fa25dcb303ce688 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Thu, 30 Jan 2025 01:06:14 -0500 Subject: [PATCH 09/21] refactor(compute): use index-based null instead of binary; uint dtype for indices --- src/copairs/compute.py | 91 ++++++---------------------- src/copairs/map/average_precision.py | 10 +-- src/copairs/map/multilabel.py | 10 +-- tests/test_map.py | 27 ++++++--- 4 files changed, 46 insertions(+), 92 deletions(-) diff --git a/src/copairs/compute.py b/src/copairs/compute.py index 6986e58..2119fe7 100644 --- a/src/copairs/compute.py +++ b/src/copairs/compute.py @@ -289,81 +289,30 @@ def get_distance_fn(distance: Union[str, Callable]) -> Callable: return batch_processing(distance_fn) -def random_binary_matrix( - n: int, m: int, k: int, rng: Optional[np.random.Generator] -) -> np.ndarray: - """Generate a random binary matrix with a fixed number of 1's per row. - - This function creates an `n x m` binary matrix where each row contains exactly - `k` ones, with the positions of the ones randomized using a specified random - number generator (RNG). - - Parameters: - ---------- - n : int - Number of rows in the matrix. - m : int - Number of columns in the matrix. - k : int - Number of 1's to be placed in each row. Must satisfy `k <= m`. - rng : Optional[np.random.Generator] - A NumPy random number generator instance used for shuffling the positions - of the ones in each row. If None, a new Generator will be created using - the default random seed. +def random_binary_matrix(n, m, k, rng): + """Generate a indices of k values in 1 per row in a random binary n*m matrix. + Args: + n: Number of rows. + m: Number of columns. + k: Number of 1's per row. Returns: ------- np.ndarray A binary matrix of shape `(n, m)` with exactly `k` ones per row. """ - # Initialize the binary matrix with all zeros - matrix = np.zeros((n, m), dtype=int) - - # Fill the first `k` elements of each row with ones - matrix[:, :k] = 1 - - # Randomly shuffle each row to distribute the ones across the columns - rng.permuted(matrix, axis=1, out=matrix) + dtype = np.uint16 if m < 2**16 else np.uint32 + indices = np.tile(np.arange(m, dtype=dtype), (n, 1)) + rng.permuted(indices, axis=1, out=indices) + return np.sort(indices[:, :k], axis=1) - return matrix - -def average_precision(rel_k: np.ndarray) -> np.ndarray: - """Compute the Average Precision (AP) for a binary list of relevance scores. - - Average Precision (AP) is a performance metric for ranking tasks, which calculates - the weighted mean of precision values at the positions where relevant items occur - in a sorted list. The relevance list should be binary (1 for relevant items, 0 - for non-relevant). - - Parameters: - ---------- - rel_k : np.ndarray - A 2D binary array where each row represents a ranked list of items, and each - element indicates the relevance of the item (1 for relevant, 0 for non-relevant). - - Returns: - ------- - np.ndarray - A 1D array of Average Precision (AP) scores, one for each row in the input array. - """ - - # Cumulative sum of relevance scores along the row (True Positives at each rank) - tp = np.cumsum(rel_k, axis=1) - - # Total number of relevant items (last value in cumulative sum per row) - num_pos = tp[:, -1] - - # Rank positions (1-based index for each column) - k = np.arange(1, rel_k.shape[1] + 1) - - # Precision at each rank - pr_k = tp / k - - # Calculate AP: Weighted sum of precision values, normalized by total relevant items - ap = (pr_k * rel_k).sum(axis=1) / num_pos - - return ap +def average_precision(rel_k) -> np.ndarray: + """Compute average precision based on binary list indices""" + num_pos = rel_k.shape[1] + pr_k = np.arange(1, num_pos + 1, dtype=np.float32) / (rel_k + 1) + ap_values = pr_k.sum(axis=1) / num_pos + return ap_values def ap_contiguous( @@ -395,10 +344,7 @@ def ap_contiguous( # Convert counts into cutoff indices to segment relevance labels cutoffs = to_cutoffs(counts) - # Calculate the number of positive pairs for each profile - num_pos = np.add.reduceat(rel_k_list, cutoffs) - - # Compute the cumulative shift for handling contiguous true positives + num_pos = np.add.reduceat(rel_k_list, cutoffs, dtype=np.uint32) shift = np.empty_like(num_pos) shift[0], shift[1:] = 0, num_pos[:-1] @@ -453,8 +399,7 @@ def random_ap(num_perm: int, num_pos: int, total: int, seed: int): # Compute Average Precision (AP) scores for each row of the binary matrix null_dist = average_precision(rel_k) - - return null_dist + return null_dist.astype(np.float32) def null_dist_cached( diff --git a/src/copairs/map/average_precision.py b/src/copairs/map/average_precision.py index 1f63f3c..8c7104e 100644 --- a/src/copairs/map/average_precision.py +++ b/src/copairs/map/average_precision.py @@ -54,8 +54,8 @@ def build_rank_lists( # Combine relevance labels: 1 for positive pairs, 0 for negative pairs labels = np.concatenate( [ - np.ones(pos_pairs.size, dtype=np.int32), # Label positive pairs - np.zeros(neg_pairs.size, dtype=np.int32), # Label negative pairs + np.ones(pos_pairs.size, dtype=np.uint32), + np.zeros(neg_pairs.size, dtype=np.uint32), ] ) @@ -78,7 +78,7 @@ def build_rank_lists( # Find unique profile indices and count their occurrences in the pairs paired_ix, counts = np.unique(ix, return_counts=True) - return paired_ix, rel_k_list, counts + return paired_ix, rel_k_list, counts.astype(np.uint32) def average_precision( @@ -193,7 +193,7 @@ def average_precision( # Convert positive pairs to a NumPy array for efficient computation pos_pairs = np.fromiter( itertools.chain.from_iterable(pos_pairs.values()), - dtype=np.dtype((np.int32, 2)), + dtype=np.dtype((np.uint32, 2)), count=pos_total, ) @@ -207,7 +207,7 @@ def average_precision( # Convert negative pairs to a NumPy array for efficient computation neg_pairs = np.fromiter( itertools.chain.from_iterable(neg_pairs.values()), - dtype=np.dtype((np.int32, 2)), + dtype=np.dtype((np.uint32, 2)), count=neg_total, ) diff --git a/src/copairs/map/multilabel.py b/src/copairs/map/multilabel.py index ff124a3..25ff6ff 100644 --- a/src/copairs/map/multilabel.py +++ b/src/copairs/map/multilabel.py @@ -48,8 +48,8 @@ def build_rank_lists_multi(pos_pairs, pos_sims, pos_counts, negs_for): neg_ix = np.repeat(query, neg_counts) labels = np.concatenate( [ - np.ones(mpos_pairs.size, dtype=np.int32), - np.zeros(len(neg_sims), dtype=np.int32), + np.ones(mpos_pairs.size, dtype=np.uint32), + np.zeros(len(neg_sims), dtype=np.uint32), ] ) @@ -89,13 +89,13 @@ def average_precision( logger.info("Finding positive pairs...") pos_pairs = matcher.get_all_pairs(sameby=pos_sameby, diffby=pos_diffby) pos_keys = pos_pairs.keys() - pos_counts = np.fromiter(map(len, pos_pairs.values()), dtype=np.int32) + pos_counts = np.fromiter(map(len, pos_pairs.values()), dtype=np.uint32) pos_total = sum(pos_counts) if pos_total == 0: raise UnpairedException("Unable to find positive pairs.") pos_pairs = np.fromiter( itertools.chain.from_iterable(pos_pairs.values()), - dtype=np.dtype((np.int32, 2)), + dtype=np.dtype((np.uint32, 2)), count=pos_total, ) @@ -106,7 +106,7 @@ def average_precision( raise UnpairedException("Unable to find any negative pairs.") neg_pairs = np.fromiter( itertools.chain.from_iterable(neg_pairs.values()), - dtype=np.dtype((np.int32, 2)), + dtype=np.dtype((np.uint32, 2)), count=neg_total, ) diff --git a/tests/test_map.py b/tests/test_map.py index b18ca9e..e7ac9da 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -14,20 +14,28 @@ SEED = 0 +def binary2indices(arr: np.ndarray) -> np.ndarray: + """Convert a binary matrix to a list of indices.""" + return np.where(arr == 1)[1].reshape(arr.shape[0], arr.sum(axis=1)[0]) + + def test_random_binary_matrix(): """Test the random binary matrix generation.""" rng = np.random.default_rng(SEED) + # Test with n=3, m=4, k=2 - A = compute.random_binary_matrix(3, 4, 2, rng) - assert A.shape == (3, 4) - assert np.all(np.sum(A, axis=1) == 2) - assert np.all((A >= 0) | (A <= 1)) + indices = compute.random_binary_matrix(3, 4, 2, rng) + assert indices.shape == (3, 2) + assert np.all(indices < 4) + assert np.all(indices >= 0) + assert np.unique(indices, axis=1).shape == indices.shape # Test with n=5, m=6, k=3 - B = compute.random_binary_matrix(5, 6, 3, rng) - assert B.shape == (5, 6) - assert np.all(np.sum(B, axis=1) == 3) - assert np.all((B == 0) | (B <= 1)) + indices = compute.random_binary_matrix(5, 6, 3, rng) + assert indices.shape == (5, 3) + assert np.all(indices < 6) + assert np.all(indices >= 0) + assert np.unique(indices, axis=1).shape == indices.shape def test_compute_ap(): @@ -50,7 +58,8 @@ def test_compute_ap(): .apply(lambda x: np.array(df.y_true[0])[x]) ) rel_k = np.stack(rel_k) - ap = compute.average_precision(rel_k) + + ap = compute.average_precision(binary2indices(rel_k)) ap_sklearn = df.apply( lambda x: average_precision_score(x["y_true"], x["y_pred"]), axis=1 From df344c64a0c4d7488196c4ec9ee57a8d7eb71cb7 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:33:08 -0500 Subject: [PATCH 10/21] chore: ruff format --- src/copairs/map/map.py | 11 +++++++++-- tests/test_map.py | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/copairs/map/map.py b/src/copairs/map/map.py index 1ff7684..861e4e3 100644 --- a/src/copairs/map/map.py +++ b/src/copairs/map/map.py @@ -11,7 +11,12 @@ def mean_average_precision( - ap_scores: pd.DataFrame, sameby, null_size: int, threshold: float, seed: int, max_workers: int = 32 + ap_scores: pd.DataFrame, + sameby, + null_size: int, + threshold: float, + seed: int, + max_workers: int = 32, ) -> pd.DataFrame: """Calculate the Mean Average Precision (mAP) score and associated p-values. @@ -77,7 +82,9 @@ def get_p_value(params): # Compute p-values for each group using the null distributions params = map_scores[["mean_average_precision", "indices"]] - map_scores["p_value"] = thread_map(get_p_value, params.values, leave=False, max_workers=max_workers) + map_scores["p_value"] = thread_map( + get_p_value, params.values, leave=False, max_workers=max_workers + ) # Perform multiple testing correction on p-values reject, pvals_corrected, alphacSidak, alphacBonf = multipletests( diff --git a/tests/test_map.py b/tests/test_map.py index e7ac9da..4beeaaf 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -22,7 +22,7 @@ def binary2indices(arr: np.ndarray) -> np.ndarray: def test_random_binary_matrix(): """Test the random binary matrix generation.""" rng = np.random.default_rng(SEED) - + # Test with n=3, m=4, k=2 indices = compute.random_binary_matrix(3, 4, 2, rng) assert indices.shape == (3, 2) From e36c3b26eb83aadcab1875f19313e327324fd100 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:05:44 -0500 Subject: [PATCH 11/21] chore(demo): add reference_index to pos_sameby, increase null size --- examples/mAP_demo.ipynb | 267 ++++++++++++++++++++++------------------ 1 file changed, 149 insertions(+), 118 deletions(-) diff --git a/examples/mAP_demo.ipynb b/examples/mAP_demo.ipynb index 5f25e41..1d98b24 100644 --- a/examples/mAP_demo.ipynb +++ b/examples/mAP_demo.ipynb @@ -1132,7 +1132,7 @@ "outputs": [], "source": [ "# positive pairs are replicates of the same treatment\n", - "pos_sameby = [\"Metadata_broad_sample\"]\n", + "pos_sameby = [\"Metadata_broad_sample\", \"Metadata_reference_index\"]\n", "pos_diffby = []\n", "\n", "neg_sameby = []\n", @@ -1157,7 +1157,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "51509158c2e84267b94e8d0cf5952604", + "model_id": "4af9b0bae8b94951aedb5a11e4cb980b", "version_major": 2, "version_minor": 0 }, @@ -1171,7 +1171,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5458f7a2a5904b7685560ac4e20d3dd8", + "model_id": "e2248bbf1ad34dfdb1a07fec3b4b8cfb", "version_major": 2, "version_minor": 0 }, @@ -1182,6 +1182,14 @@ "metadata": {}, "output_type": "display_data" }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/akalinin/Projects/copairs/src/copairs/compute.py:150: RuntimeWarning: invalid value encountered in divide\n", + " ap_scores = np.add.reduceat(pr_k * rel_k_list, cutoffs) / num_pos\n" + ] + }, { "data": { "text/html": [ @@ -1575,7 +1583,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b55cf11c765b4af98dca44f808372955", + "model_id": "1f294742f68b4481adae455126b9168e", "version_major": 2, "version_minor": 0 }, @@ -1589,7 +1597,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f470ba4162d4425f8983d7f7c52ff982", + "model_id": "f993a3498f8a486ca65810bc41281a12", "version_major": 2, "version_minor": 0 }, @@ -1622,6 +1630,7 @@ " \n", " \n", " Metadata_broad_sample\n", + " Metadata_reference_index\n", " mean_average_precision\n", " p_value\n", " corrected_p_value\n", @@ -1634,131 +1643,153 @@ " \n", " 0\n", " BRD-A69275535-001-01-5\n", + " -1\n", " 0.575629\n", - " 0.017698\n", - " 0.023857\n", + " 1.725598e-02\n", + " 0.023276\n", " True\n", " True\n", - " 1.622390\n", + " 1.633101\n", " \n", " \n", " 1\n", " BRD-A69636825-003-04-7\n", + " -1\n", " 0.693806\n", - " 0.003700\n", - " 0.006922\n", + " 3.477997e-03\n", + " 0.006507\n", " True\n", " True\n", - " 2.159775\n", + " 2.186605\n", " \n", " \n", " 2\n", " BRD-A69815203-001-07-6\n", + " -1\n", " 1.000000\n", - " 0.000100\n", - " 0.000341\n", + " 9.999990e-07\n", + " 0.000008\n", " True\n", " True\n", - " 3.467064\n", + " 5.081670\n", " \n", " \n", " 3\n", " BRD-A70858459-001-01-7\n", + " -1\n", " 0.777173\n", - " 0.000600\n", - " 0.001289\n", + " 8.279992e-04\n", + " 0.001921\n", " True\n", " True\n", - " 2.889828\n", + " 2.716482\n", " \n", " \n", " 4\n", " BRD-A72309220-001-04-1\n", + " -1\n", " 0.716927\n", - " 0.002200\n", - " 0.004253\n", + " 2.323998e-03\n", + " 0.004493\n", " True\n", " True\n", - " 2.371314\n", + " 2.347458\n", " \n", " \n", " 5\n", " BRD-A72390365-001-15-2\n", + " -1\n", " 0.934444\n", - " 0.000100\n", - " 0.000341\n", + " 2.799997e-05\n", + " 0.000108\n", " True\n", " True\n", - " 3.467064\n", + " 3.965506\n", " \n", " \n", " 6\n", " BRD-A73368467-003-17-6\n", + " -1\n", " 0.926032\n", - " 0.000100\n", - " 0.000341\n", + " 3.699996e-05\n", + " 0.000134\n", " True\n", " True\n", - " 3.467064\n", + " 3.872491\n", " \n", " \n", " 7\n", " BRD-A74980173-001-11-9\n", + " -1\n", " 0.765931\n", - " 0.000600\n", - " 0.001289\n", + " 1.017999e-03\n", + " 0.002187\n", " True\n", " True\n", - " 2.889828\n", + " 2.660188\n", " \n", " \n", " 8\n", " BRD-A81233518-004-16-1\n", + " -1\n", " 0.621183\n", - " 0.009399\n", - " 0.013978\n", + " 9.594990e-03\n", + " 0.014269\n", " True\n", " True\n", - " 1.854552\n", + " 1.845592\n", " \n", " \n", " 9\n", " BRD-A82035391-001-02-7\n", + " -1\n", " 0.318066\n", - " 0.260374\n", - " 0.264942\n", + " 2.536767e-01\n", + " 0.258127\n", " False\n", " False\n", - " 0.576849\n", + " 0.588166\n", " \n", " \n", "\n", "" ], "text/plain": [ - " Metadata_broad_sample mean_average_precision p_value \\\n", - "0 BRD-A69275535-001-01-5 0.575629 0.017698 \n", - "1 BRD-A69636825-003-04-7 0.693806 0.003700 \n", - "2 BRD-A69815203-001-07-6 1.000000 0.000100 \n", - "3 BRD-A70858459-001-01-7 0.777173 0.000600 \n", - "4 BRD-A72309220-001-04-1 0.716927 0.002200 \n", - "5 BRD-A72390365-001-15-2 0.934444 0.000100 \n", - "6 BRD-A73368467-003-17-6 0.926032 0.000100 \n", - "7 BRD-A74980173-001-11-9 0.765931 0.000600 \n", - "8 BRD-A81233518-004-16-1 0.621183 0.009399 \n", - "9 BRD-A82035391-001-02-7 0.318066 0.260374 \n", - "\n", - " corrected_p_value below_p below_corrected_p -log10(p-value) \n", - "0 0.023857 True True 1.622390 \n", - "1 0.006922 True True 2.159775 \n", - "2 0.000341 True True 3.467064 \n", - "3 0.001289 True True 2.889828 \n", - "4 0.004253 True True 2.371314 \n", - "5 0.000341 True True 3.467064 \n", - "6 0.000341 True True 3.467064 \n", - "7 0.001289 True True 2.889828 \n", - "8 0.013978 True True 1.854552 \n", - "9 0.264942 False False 0.576849 " + " Metadata_broad_sample Metadata_reference_index mean_average_precision \\\n", + "0 BRD-A69275535-001-01-5 -1 0.575629 \n", + "1 BRD-A69636825-003-04-7 -1 0.693806 \n", + "2 BRD-A69815203-001-07-6 -1 1.000000 \n", + "3 BRD-A70858459-001-01-7 -1 0.777173 \n", + "4 BRD-A72309220-001-04-1 -1 0.716927 \n", + "5 BRD-A72390365-001-15-2 -1 0.934444 \n", + "6 BRD-A73368467-003-17-6 -1 0.926032 \n", + "7 BRD-A74980173-001-11-9 -1 0.765931 \n", + "8 BRD-A81233518-004-16-1 -1 0.621183 \n", + "9 BRD-A82035391-001-02-7 -1 0.318066 \n", + "\n", + " p_value corrected_p_value below_p below_corrected_p \\\n", + "0 1.725598e-02 0.023276 True True \n", + "1 3.477997e-03 0.006507 True True \n", + "2 9.999990e-07 0.000008 True True \n", + "3 8.279992e-04 0.001921 True True \n", + "4 2.323998e-03 0.004493 True True \n", + "5 2.799997e-05 0.000108 True True \n", + "6 3.699996e-05 0.000134 True True \n", + "7 1.017999e-03 0.002187 True True \n", + "8 9.594990e-03 0.014269 True True \n", + "9 2.536767e-01 0.258127 False False \n", + "\n", + " -log10(p-value) \n", + "0 1.633101 \n", + "1 2.186605 \n", + "2 5.081670 \n", + "3 2.716482 \n", + "4 2.347458 \n", + "5 3.965506 \n", + "6 3.872491 \n", + "7 2.660188 \n", + "8 1.845592 \n", + "9 0.588166 " ] }, "execution_count": 9, @@ -1768,7 +1799,7 @@ ], "source": [ "replicate_maps = map.mean_average_precision(\n", - " replicate_aps, pos_sameby, null_size=10000, threshold=0.05, seed=0\n", + " replicate_aps, pos_sameby, null_size=1000000, threshold=0.05, seed=0\n", ")\n", "replicate_maps[\"-log10(p-value)\"] = -replicate_maps[\"corrected_p_value\"].apply(np.log10)\n", "replicate_maps.head(10)" @@ -1788,7 +1819,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAGwCAYAAABVdURTAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABPE0lEQVR4nO3dd3gU5f428Ht2k91NXVJIDyEQWoBADKIBD6GH8kOwIE1Aj1jBI4J6iIh4UInH7lGKggSPB0Sl+iKCSBUIIiTRUKQESCgplPSe3ef9I7CyppDdbEkm9+e69tJ95pmZ70zI7p2ZZ2YkIYQAERERkUwo7F0AERERkSUx3BAREZGsMNwQERGRrDDcEBERkaww3BAREZGsMNwQERGRrDDcEBERkaw42LsAW9Pr9bh8+TLc3NwgSZK9yyEiIqIGEEKgsLAQAQEBUCjqPzbT4sLN5cuXERwcbO8yiIiIyAwXLlxAUFBQvX1aXLhxc3MDUL1z3N3d7VwNERERNURBQQGCg4MN3+P1aXHh5uapKHd3d4YbIiKiZqYhQ0o4oJiIiIhkheGGiIiIZIXhhoiIiGSF4YaIiIhkheGGiIiIZIXhhoiIiGSF4YaIiIhkxa7hZsmSJYiIiDDccyY6Oho//PBDnf1XrlwJSZKMXhqNxoYVExERUVNn15v4BQUF4a233kKHDh0ghMAXX3yB0aNHIzk5GV27dq11Hnd3d5w8edLwns+HIiIiolvZNdyMGjXK6P2bb76JJUuW4ODBg3WGG0mS4Ofn1+B1lJeXo7y83PC+oKDAvGKJiIioWWgyY250Oh3WrFmD4uJiREdH19mvqKgIISEhCA4OxujRo3Hs2LF6lxsfHw+tVmt48aGZRERE8iYJIYQ9C0hNTUV0dDTKysrg6uqK1atXY8SIEbX2TUxMxOnTpxEREYH8/Hy8++672Lt3L44dO1bnE0JrO3ITHByM/Px8PluKiIjs6vfCEsw8kYHzpRVo56xG31auWJediwq9HiNat8LCjkHIKCvHcycycKqoDE4OClToBRwlCZMCvBDXzh9KE4ZnlOn0ePXMJWzMyQOEgA5AsU4PBYAorTM+69oWjpICM//IQGJeEVo5KDG3nT9OlZTji0tXIQCM8/fEK+0C4KiQ8PnFK/goPRulOj3aqB1xrOTP71sXhYS0mB4W21cFBQXQarUN+v62e7ipqKhARkYG8vPzsXbtWixfvhx79uxBeHj4beetrKxEly5dMGHCBLz++usNWp8pO4eIiMhacsorcc+hEyiu0kOH6lMp+lumKwD8X2st9ucVI6+yCrq/zC8BmN3WDy+ENnyoxj9PXsCXl68ZredWHZxUcHNwwG+FJTXWd+t6p7fxQbirE545nl7v+tpoVDgUffvv84Yw5fvb7k8FV6lUCAsLAwBERUXh119/xUcffYRPP/30tvM6OjoiMjISZ86csXaZREREFrUvrwgFVX/GjL8GDj2ALVfzUVXHIQgBYF32dZPCzfrs3DqDDQCcLq0AUFHvMqrXm4szJWWQbryvS0ZZ/cuyliYz5uYmvV5vdBqpPjqdDqmpqfD397dyVURERJbl2IDTSQrU38dRMu1r3FFhmSuMHSUJjtLtqrMfu4abuLg47N27F+fPn0dqairi4uKwe/duTJo0CQAwZcoUxMXFGfovWLAAP/74I86ePYukpCQ8/PDDSE9Px7Rp0+y1CURERGYZ4OmGILUjlDfe1/aF/FiQN8Kc1YY+f/VEcGuT1vl4UP39/9bKBSO9tYZaFECt634iuDWmBnpBAPUGnL5aF5PqsxS7npbKycnBlClTkJmZCa1Wi4iICGzbtg1DhgwBAGRkZECh+PPHnZubi8cffxxZWVnw8PBAVFQUDhw40KDxOURERE2Jq4MS/y+qA14/cxmnS8rRyUWDfh6u+DorF6V6PUa2boWng1vjmTY+eCPtMo4VlsJRIUEPQKNQYKK/F8b5e5q0zpkhvnBzUGJDdi50QqBUp8fl8kqoFBL+r7UWr4YFQgkJ757Pws+5hfBydMALbf1wtrS8eqyOqB5QPMnfE5IkYXVEOyzOyEGRTo8INzW+uJxrWFe4ixrr7uhg4b3WMHYfUGxrHFBMRETU/Jjy/d3kxtwQERERNQbDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyYqDvQsgIiKyliq9wOrMazhdUoYQJzUmB3hBrfjz7/ozJWX4NisXlXqBka21iNK6WLyG1MISbMrJgwTgPl8PhLs6WXwdZIzhhoiIZEkvBP5+9By2XyuAgwRUCWDLlTx80yMMDgoJvxeW4N6k06gUAhKApRdysKJbKIa11lqshn25hRj/WxoAQABYeuEKvu7RHn08XC22DqqJp6WIiEiWDuYV48drBRAAKkV1uDiQV4wd1wsAAG+dzUSFXkAnqoOPAPDqmUsWreFfZy5Df2P5OgHohMAbZy9bdB1UE8MNERHJ0rXKqtrbK6rbr1RUQX9LuwBwvY55zHW10ngdegBXKyy7DqqJ4YaIiGQpws0JDpJxmwJApLszAKBPK1ejL0ElgDstPOYmWusK5V/WcbcVxvWQMYYbIiKSpRAnNRaHt4VaUZ1wHCUJ73cORpcbA3r/2c4fMZ5uhv6dXTX4qHMbi9awsGMg7rgRpgCgl9YFr3cItOg6qCZJCCHsXYQtFRQUQKvVIj8/H+7u7vYuh4iIrKyoSodL5ZXwVzvC3UFpNE0IgYvlldAJgWCNCkpJqmMp5hNCIKOsAgDQRqOCZIV1tASmfH/zaikiIpI1VwclOv0l1NwkSRKCNSqrrl+SJIQ4qa26DjLG01JEREQkKww3REREJCsMN0RERCQrDDdEREQkKww3REREJCsMN0RERCQrDDdEREQkKww3REREJCsMN0RERCQrDDdEREQkKww3REREJCsMN0RERCQrDDdEREQkKww3REREJCsMN0RERCQrDDdEREQkKww3REREJCsMN0RERCQrDDdEREQkK3YNN0uWLEFERATc3d3h7u6O6Oho/PDDD/XO8+2336Jz587QaDTo3r07tmzZYqNqiYiIqDmwa7gJCgrCW2+9hSNHjuDw4cMYOHAgRo8ejWPHjtXa/8CBA5gwYQIee+wxJCcnY8yYMRgzZgyOHj1q48qJiIioqZKEEMLeRdzK09MT77zzDh577LEa08aNG4fi4mJs3rzZ0Hb33XejZ8+eWLp0aa3LKy8vR3l5ueF9QUEBgoODkZ+fD3d3d8tvABEREVlcQUEBtFptg76/m8yYG51OhzVr1qC4uBjR0dG19klMTMTgwYON2mJjY5GYmFjncuPj46HVag2v4OBgi9ZNRERETYvdw01qaipcXV2hVqvx1FNPYcOGDQgPD6+1b1ZWFnx9fY3afH19kZWVVefy4+LikJ+fb3hduHDBovUTERFR0+Jg7wI6deqElJQU5OfnY+3atZg6dSr27NlTZ8AxlVqthlqttsiyiIiIqOmze7hRqVQICwsDAERFReHXX3/FRx99hE8//bRGXz8/P2RnZxu1ZWdnw8/Pzya1EhERUdNn99NSf6XX640GAN8qOjoaO3bsMGrbvn17nWN0iIiIqOWx65GbuLg4DB8+HG3atEFhYSFWr16N3bt3Y9u2bQCAKVOmIDAwEPHx8QCA5557DjExMXjvvfcwcuRIrFmzBocPH8Znn31mz80gIiKiJsSu4SYnJwdTpkxBZmYmtFotIiIisG3bNgwZMgQAkJGRAYXiz4NLffr0werVq/HKK6/g5ZdfRocOHbBx40Z069bNXptARERETUyTu8+NtZlynTwRERE1Dc3yPjdERERElsBwQ0RERLJi90vBiYjItr68fBXvncvCtUodNAoJo31a4V8dAuGiVCIxrwjzT1/EmZJyCADBGhXi2vkDAN4+l4XCKh0GebljflggnJWW//v4WkUV4k5dwMH8YpTq9FApJHRy0SC+YzA6uWgsvj6SJ465ISJqQb7OvI7n/sgwapMADPfW4qV2fhjy6ylU1vG1IAEQqD7kP8xbixXdQy1am04IDD98CseKSqG7pV0BQOugxN67OqO1ytGi66Tmg2NuiIioVqszr9VoEwC2XM3Ht5nXobtNsAEA/Y3+xTpdrX3NdbqkDL//JdjcXF9ulQ67rhdadH0kXww3REQtiGTvAuohNenqqDlhuCEiakEmBnjVaJMA/F9rLR7y94JSqj1gCPwZjBQ3+rsolRatLcxZjZ5uTvjrUhUAPB2VGOjJoQTUMAw3REQtRJVeYKyvB97rFIwAlSNUkgR3pQKT/b3wny4h6OSiwdqe7dHTzQkuCgnOCgW6uGiwslsovugeiq6uTmijUWFKQHV/S1NKElb3aI97fVrBT+UAd6UC3o5K9PVwxabIDvBW8RoYahgOKCYikrlrFVV4+vh5/JxbBI1CwvNt/fBsGx9IdRylIWqKOKCYiIgMnjp+HvvziiAAlOoFFp7NxLfZufYui8hqGG6IiGSsTKfHz7lF0N1yjF4C8OPVfLvVRGRtDDdERDLmIElw+MvZJwUAJyvcgI+oqeC/biIiGXNQSHgm2MfwXglAIUmYFtTafkURWRmHnhMRyVxcO3/4qR2x83ohXJUKPBnsgx5uzvYui8hqGG6IiGROkiT8Pag1/s6jNdRC8LQUERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyQrDDREREckKww0RERHJCsMNERERyYqDvQsgIqI/nSkpw9mScrR1UqOji8be5RA1Sww3RERNxKKMHLyedtnwfk6oH2a29bNjRUTNE09LERE1AceKSo2CDQC8dS4LyQUldqqIqPliuCEiagJOFpfV0V5q40qImj+GGyKiJqCNRlVre3Ad7URUN4YbIqImIMrdGY8EeAEApBttE/090aeVq/2KImqm7Bpu4uPjceedd8LNzQ0+Pj4YM2YMTp48We88K1euhCRJRi+NhlcUEFHzJkkS4jsGYU2Pdni9QyBWR7TDe52CIUnS7WcmIiN2vVpqz549mD59Ou68805UVVXh5ZdfxtChQ3H8+HG4uLjUOZ+7u7tRCOIvPxHJgSRJ6O/pjv6e9q6EqHmza7jZunWr0fuVK1fCx8cHR44cQb9+/eqcT5Ik+Pnx8kgiIiKqqUmNucnPzwcAeHrW/2dLUVERQkJCEBwcjNGjR+PYsWN19i0vL0dBQYHRi4iIiOSryYQbvV6PmTNnom/fvujWrVud/Tp16oQVK1Zg06ZN+N///ge9Xo8+ffrg4sWLtfaPj4+HVqs1vIKDg621CURERNQESEIIYe8iAODpp5/GDz/8gH379iEoKKjB81VWVqJLly6YMGECXn/99RrTy8vLUV5ebnhfUFCA4OBg5Ofnw93d3SK1ExERkXUVFBRAq9U26Pu7STx+YcaMGdi8eTP27t1rUrABAEdHR0RGRuLMmTO1Tler1VCr1ZYok4iIiJoBu56WEkJgxowZ2LBhA3bu3InQ0FCTl6HT6ZCamgp/f38rVEhERETNjV2P3EyfPh2rV6/Gpk2b4ObmhqysLACAVquFk5MTAGDKlCkIDAxEfHw8AGDBggW4++67ERYWhry8PLzzzjtIT0/HtGnT7LYdRERE1HTYNdwsWbIEANC/f3+j9oSEBDzyyCMAgIyMDCgUfx5gys3NxeOPP46srCx4eHggKioKBw4cQHh4uK3KJiIioiasyQwothVTBiQRERFR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q+Hn54eQkBA8/fTTGDx4ML777jtbbRoRWRnDDRE1WV988QW8vb1x6NAhPPvss3j66acxduxY9OnTB0lJSRg6dCgmT56MkpISAIAQAgkJCXj44YfRuXNnhIWFYe3atbddj5OTEyoqKqy9OURkIww3RNRk9ejRA6+88go6dOiAuLg4aDQaeHt74/HHH0eHDh3w6quv4tq1a/j9998BAD/99BNKSkoQGxsLAHj44Yfx+eef17l8IQR++uknbNu2DQMHDrTJNhGR9THcEFGTFRERYfh/pVIJLy8vdO/e3dDm6+sLAMjJyQEArFixAuPGjYODgwMAYMKECdi/fz/S0tKMlrt582a4urpCo9Fg+PDhGDduHF577TUrbw0R2QrDDRE1WY6OjkbvJUkyapMkCQCg1+tx/fp1bNiwAYsXL4aDgwMcHBwQGBiIqqqqGgOLBwwYgJSUFJw+fRqlpaX44osv4OLiYv0NIiKbcLB3AURElrBq1SoEBQVh48aNRu0//vgj3nvvPSxYsABKpRIA4OLigrCwMDtUSUS2wHBDRLLw+eef48EHH0S3bt2M2oODgxEXF4etW7di5MiRdqqOiGyJp6WIqNlLS0vDb7/9hgceeKDGNK1Wi0GDBtU7sJiI5EUSQgh7F0FERERkKTxyQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESy8v8BqQCKWcqb55oAAAAASUVORK5CYII=", + "image/png": "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ArxcXQYREbkQ/0wlIiIi2WJQISIiItlyaVD55ZdfMHLkSERERECSJGzYsMGV5RAREZHMuDSolJaWonv37li0aJEryyAiIiKZculg2uHDh2P48OGNbq/T6aDT6UzPi4qKHFEWERERyYRbjVGZP38+/P39TY/o6GhXl0REREQO5FZB5cUXX0RhYaHpcf78eVeXRERERA7kVvOoqNVqqNVqV5dBRERETuJWPSpERETUsjCoEBERkWy59NRPSUkJTp8+bXqemZmJ1NRUtGrVCm3atHFhZURERCQHLg0qBw8exMCBA03PZ8yYAQCYMmUKli9f7qKqiIiISC5cGlQGDBgAN755MxERETkYx6gQERGRbDGoEBERkWwxqBAREZFsMagQERGRbDGoEBERkWwxqBAREZFsMagQERGRbDGoEBERkWwxqLgZg1FAbzC6ugwiIiKncOnMtNR4eoMRr317HKsOnIdRCIzoFo5370+AVsUfIRERNV/sUXETC7emY8W+czAYBYQAfjiajbnfHnd1WURERA7FoOImfjxxBbXvimQUwJaTOS6rh4iIyBkYVNyEt9oD0nXLtCqlS2ohIiJyFgYVNzF1YCwAQCEB0h+J5ak74lxYERERkeNxJKabuKNzKL58+BasOlA9TmV09wgM7xbu6rKIiIgcikHFjdzaIQi3dghydRlEREROw1M/REREJFsMKkRERCRbDCpEREQkWwwqdlChNyD9SjFyiitcXQoREVGzwsG0TZR6vgD/t/wA8ksrAQB/v60dXhrRBZJ0/awnREREZC32qDRBZZURD39xAAVllaZly37NxLdHLrmwKiIiouaDQaUJLhaUI6+kEsZac9t7KCQczrrmuqKIiIiaEZ76uU5OUQVmfnUEh7KuoZW3Cq/cFY9hN4VZbNtKq4IEXHcPHoFW3mqn1EpERNTcsUelFoNRYEryfuzOyENZpQEXr5XjyRWHcPic5R4Sf60nnh7cAUB1T4pCAsL9vfBgUowzyyYiImq22KNSy7n8MpzMLjY9FwCUkoTNxy6jZ5tAi6+ZPrgjuoT74UBmPlr5qDChTxsEaFVOqpiIiKh5Y1CpxVNZ90odAcDDwvLahnYNw9Culk8PERERke146qeWyAAv9O8YDMUfuUQhVYeXe3tGubYwIiKiFoo9KrVIkoRPJvXCez+mYX9mPoJ91ZgxpCNig31c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", "text/plain": [ "
" ] @@ -2479,7 +2510,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "d6f90c7f26924332b4a4e23ba90dd98e", + "model_id": "3548e3d76a50442f8bd81ca1134e3718", "version_major": 2, "version_minor": 0 }, @@ -2493,7 +2524,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e6891153024b485a92a556545e04a8eb", + "model_id": "5f77a556df084428a019a8ba2480599c", "version_major": 2, "version_minor": 0 }, @@ -2700,7 +2731,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "587b411cad734aa9ab356ee6ba537fd5", + "model_id": "f30cc784702349679561e80c0c71a669", "version_major": 2, "version_minor": 0 }, @@ -2714,7 +2745,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c051523be08049089850e2cda87e7b5c", + "model_id": "c99f02640b394aaf8bf31b346fa610b0", "version_major": 2, "version_minor": 0 }, @@ -2760,101 +2791,101 @@ " 0\n", " ADRA1A\n", " 0.250000\n", - " 0.113389\n", - " 0.192056\n", + " 0.112414\n", + " 0.186114\n", " False\n", " False\n", - " 0.716573\n", + " 0.730220\n", " \n", " \n", " 1\n", " ADRA2A\n", " 0.250000\n", - " 0.113389\n", - " 0.192056\n", + " 0.112414\n", + " 0.186114\n", " False\n", " False\n", - " 0.716573\n", + " 0.730220\n", " \n", " \n", " 2\n", " AURKA\n", " 0.625000\n", - " 0.023398\n", - " 0.101390\n", + " 0.023976\n", + " 0.103896\n", " True\n", " False\n", - " 0.994005\n", + " 0.983402\n", " \n", " \n", " 3\n", " BIRC2\n", " 0.060662\n", - " 0.379062\n", - " 0.469315\n", + " 0.380492\n", + " 0.471085\n", " False\n", " False\n", - " 0.328536\n", + " 0.326901\n", " \n", " \n", " 4\n", " CHRM1\n", " 0.098420\n", - " 0.484752\n", - " 0.484752\n", + " 0.492938\n", + " 0.492938\n", " False\n", " False\n", - " 0.314481\n", + " 0.307208\n", " \n", " \n", " 5\n", " CHRM2\n", " 0.098420\n", - " 0.484752\n", - " 0.484752\n", + " 0.492938\n", + " 0.492938\n", " False\n", " False\n", - " 0.314481\n", + " 0.307208\n", " \n", " \n", " 6\n", " CHRM3\n", " 0.098420\n", - " 0.484752\n", - " 0.484752\n", + " 0.492938\n", + " 0.492938\n", " False\n", " False\n", - " 0.314481\n", + " 0.307208\n", " \n", " \n", " 7\n", " CHRM4\n", " 0.098420\n", - " 0.484752\n", - " 0.484752\n", + " 0.492938\n", + " 0.492938\n", " False\n", " False\n", - " 0.314481\n", + " 0.307208\n", " \n", " \n", " 8\n", " CHRM5\n", " 0.098420\n", - " 0.484752\n", - " 0.484752\n", + " 0.492938\n", + " 0.492938\n", " False\n", " False\n", - " 0.314481\n", + " 0.307208\n", " \n", " \n", " 9\n", " DRD2\n", " 0.750000\n", - " 0.000900\n", - " 0.005849\n", + " 0.000670\n", + " 0.004355\n", " True\n", " True\n", - " 2.232888\n", + " 2.361012\n", " \n", " \n", "\n", @@ -2862,28 +2893,28 @@ ], "text/plain": [ " Metadata_target mean_average_precision p_value corrected_p_value \\\n", - "0 ADRA1A 0.250000 0.113389 0.192056 \n", - "1 ADRA2A 0.250000 0.113389 0.192056 \n", - "2 AURKA 0.625000 0.023398 0.101390 \n", - "3 BIRC2 0.060662 0.379062 0.469315 \n", - "4 CHRM1 0.098420 0.484752 0.484752 \n", - "5 CHRM2 0.098420 0.484752 0.484752 \n", - "6 CHRM3 0.098420 0.484752 0.484752 \n", - "7 CHRM4 0.098420 0.484752 0.484752 \n", - "8 CHRM5 0.098420 0.484752 0.484752 \n", - "9 DRD2 0.750000 0.000900 0.005849 \n", + "0 ADRA1A 0.250000 0.112414 0.186114 \n", + "1 ADRA2A 0.250000 0.112414 0.186114 \n", + "2 AURKA 0.625000 0.023976 0.103896 \n", + "3 BIRC2 0.060662 0.380492 0.471085 \n", + "4 CHRM1 0.098420 0.492938 0.492938 \n", + "5 CHRM2 0.098420 0.492938 0.492938 \n", + "6 CHRM3 0.098420 0.492938 0.492938 \n", + "7 CHRM4 0.098420 0.492938 0.492938 \n", + "8 CHRM5 0.098420 0.492938 0.492938 \n", + "9 DRD2 0.750000 0.000670 0.004355 \n", "\n", " below_p below_corrected_p -log10(p-value) \n", - "0 False False 0.716573 \n", - "1 False False 0.716573 \n", - "2 True False 0.994005 \n", - "3 False False 0.328536 \n", - "4 False False 0.314481 \n", - "5 False False 0.314481 \n", - "6 False False 0.314481 \n", - "7 False False 0.314481 \n", - "8 False False 0.314481 \n", - "9 True True 2.232888 " + "0 False False 0.730220 \n", + "1 False False 0.730220 \n", + "2 True False 0.983402 \n", + "3 False False 0.326901 \n", + "4 False False 0.307208 \n", + "5 False False 0.307208 \n", + "6 False False 0.307208 \n", + "7 False False 0.307208 \n", + "8 False False 0.307208 \n", + "9 True True 2.361012 " ] }, "execution_count": 14, @@ -2893,7 +2924,7 @@ ], "source": [ "target_maps = map.mean_average_precision(\n", - " target_aps, pos_sameby, null_size=10000, threshold=0.05, seed=0\n", + " target_aps, pos_sameby, null_size=1000000, threshold=0.05, seed=0\n", ")\n", "target_maps[\"-log10(p-value)\"] = -target_maps[\"corrected_p_value\"].apply(np.log10)\n", "target_maps.head(10)" @@ -2913,7 +2944,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAGwCAYAAABVdURTAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA98klEQVR4nO3deXhU5f338c9kmywkIRgIAUJAgkBQILJIiAVBEJUq2KqIiuhPaGWryKKiRSioUPeKoBXLUmVxQUQRUUQQEWSPZZOyL5IEUEhCAiHL/fzBkyljFjKTSSY5vF/XNdfFnPM9Z75zEmY+uc9mM8YYAQAAWISPtxsAAADwJMINAACwFMINAACwFMINAACwFMINAACwFMINAACwFMINAACwFD9vN1DZCgoKdOzYMYWGhspms3m7HQAAUAbGGGVmZqpevXry8Sl9bOayCzfHjh1TTEyMt9sAAABuOHLkiBo0aFBqzWUXbkJDQyVd2DhhYWFe7gYAAJRFRkaGYmJiHN/jpbnswk3hrqiwsDDCDQAA1UxZDinhgGIAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAGAphBsAAFBuJ87n6v7/7FeT1f9R27U79EnaKa/1ctndOBMAAHiWMUYDth3QjxnZypeUlV+gwTsPqU6AvzpF1Kj0fhi5AQAA5ZKSk6st/z/YFPK1SZ+fOO2Vfgg3AACgXPx9bEWmGUl+xUyvDIQbAABQLrUD/NUrMtwRKnwk+cqme+rW8ko/HHMDAADKbVp8rF48mKo1pzJ1hb+fRjeuqxY1grzSC+EGAACUW6Cvj8Y1qeftNiSxWwoAAFgM4QYAAFgK4QYAAFgK4QYAAFgK4QYAAFiKV8PN5MmT1b59e4WGhqpOnTrq06ePdu/eXeoys2fPls1mc3oEBgZWUscAAKCq82q4+fbbbzV06FD98MMPWr58uXJzc3XTTTcpKyur1OXCwsKUkpLieBw6dKiSOgYAAFWdV69zs2zZMqfns2fPVp06dbR582Z17ty5xOVsNpvq1q1b0e0BAIBqqEodc5Oeni5JqlWr9Ms1nzlzRrGxsYqJiVHv3r21Y8eOEmtzcnKUkZHh9AAAANZVZcJNQUGBRowYoaSkJF199dUl1jVr1kwzZ87U4sWL9d5776mgoECdOnXS0aNHi62fPHmywsPDHY+YmJiKegsAAKAKsBljjLebkKTBgwfriy++0Jo1a9SgQYMyL5ebm6sWLVqoX79+mjRpUpH5OTk5ysnJcTzPyMhQTEyM0tPTFRYW5pHeAQBAxcrIyFB4eHiZvr+rxL2lhg0bpiVLlmj16tUuBRtJ8vf3V0JCgvbu3VvsfLvdLrvd7ok2AQBANeDV3VLGGA0bNkyLFi3SN998o8aNG7u8jvz8fG3btk3R0dEV0CEAAKhuvDpyM3ToUM2bN0+LFy9WaGioUlNTJUnh4eEKCrpwm/QHHnhA9evX1+TJkyVJEydOVMeOHRUXF6fTp0/rxRdf1KFDhzRw4ECvvQ8AAFB1eDXcvPnmm5KkG264wWn6rFmz9OCDD0qSDh8+LB+f/w0wnTp1SoMGDVJqaqoiIiLUtm1brV27VvHx8ZXVNgAAqMKqzAHFlcWVA5IAAEDV4Mr3d5U5FRwAAMATCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBSCDcAAMBS/LzdAADg8nDobI5u2rhb6fkF8pX0fw0iNalpA2+3BQti5AYAUOHy8/N1/fpdSs8vuPBc0oyjJzX1UKp3G4MlEW4AABVu9eks5Zqi0/955GTlNwPLI9wAACpcbkFBsdONikk8QDkRbgAAFe7GWqHFfuHcU7dWpfcC6yPcAAAqnK+vr5a2bapAm80x7fbaNTUurr4Xu4JVcbYUAKBStAkL0cEbWnu7DVwGGLkBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACWQrgBAACW4tVwM3nyZLVv316hoaGqU6eO+vTpo927d19yuQ8//FDNmzdXYGCgrrnmGi1durQSugUAANWBV8PNt99+q6FDh+qHH37Q8uXLlZubq5tuuklZWVklLrN27Vr169dPDz/8sLZu3ao+ffqoT58+2r59eyV2DgAAqiqbMcZ4u4lCJ06cUJ06dfTtt9+qc+fOxdb07dtXWVlZWrJkiWNax44d1aZNG7311luXfI2MjAyFh4crPT1dYWFhHusdAABUHFe+v6vUMTfp6emSpFq1apVYs27dOnXv3t1pWs+ePbVu3bpi63NycpSRkeH0AAAA1lVlwk1BQYFGjBihpKQkXX311SXWpaamKioqymlaVFSUUlNTi62fPHmywsPDHY+YmBiP9g0AAKqWKhNuhg4dqu3bt2vBggUeXe/YsWOVnp7ueBw5csSj6wcAAFWLn7cbkKRhw4ZpyZIlWr16tRo0aFBqbd26dZWWluY0LS0tTXXr1i223m63y263e6xXAABQtXl15MYYo2HDhmnRokX65ptv1Lhx40suk5iYqBUrVjhNW758uRITEyuqTQAAUI14deRm6NChmjdvnhYvXqzQ0FDHcTPh4eEKCgqSJD3wwAOqX7++Jk+eLEl69NFH1aVLF7388svq1auXFixYoE2bNuntt9/22vsAAABVh1dHbt58802lp6frhhtuUHR0tOPx/vvvO2oOHz6slJQUx/NOnTpp3rx5evvtt9W6dWt99NFH+uSTT0o9CBkAAFw+qtR1bioD17kBAKD6qbbXuQEAACgvwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUwg0AALAUP1cXOH36tBYtWqTvvvtOhw4dUnZ2tmrXrq2EhAT17NlTnTp1qog+AQAAyqTMIzfHjh3TwIEDFR0drWeffVZnz55VmzZtdOONN6pBgwZauXKlevToofj4eL3//vsV2TMAAECJyjxyk5CQoAEDBmjz5s2Kj48vtubs2bP65JNP9Nprr+nIkSMaPXq0xxoFAAAoC5sxxpSl8JdfftEVV1xR5hW7Wl9ZMjIyFB4ervT0dIWFhXm7HQAAUAaufH+XebeUq0GlKgYbAABg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/sYYZWZmql69evLxKf2omstu5MbHx0cNGjTwdhuXjbCwMD5cvIjt711sf+9i+3tXRWz/S43YFOKAYgAAYCmEGwAAYCmEG1QIu92u8ePHy263e7uVyxLb37vY/t7F9veuqrD9L7sDigEAgLUxcgMAACyFcAMAACyFcAMAACyFcAMAACyFcAO3TZs2TY0aNVJgYKCuu+46bdiwocTaGTNm6He/+50iIiIUERGh7t27l1qPS3Nl+19swYIFstls6tOnT8U2aHGubv/Tp09r6NChio6Olt1u11VXXaWlS5dWUrfW4+r2f+2119SsWTMFBQUpJiZGjz32mM6dO1dJ3VrH6tWrddttt6levXqy2Wz65JNPLrnMqlWrdO2118putysuLk6zZ8+u8D5lADcsWLDABAQEmJkzZ5odO3aYQYMGmZo1a5q0tLRi6++9914zbdo0s3XrVrNr1y7z4IMPmvDwcHP06NFK7twaXN3+hQ4cOGDq169vfve735nevXtXTrMW5Or2z8nJMe3atTO33nqrWbNmjTlw4IBZtWqVSU5OruTOrcHV7T937lxjt9vN3LlzzYEDB8yXX35poqOjzWOPPVbJnVd/S5cuNU8//bT5+OOPjSSzaNGiUuv3799vgoODzciRI83OnTvN1KlTja+vr1m2bFmF9km4gVs6dOhghg4d6nien59v6tWrZyZPnlym5fPy8kxoaKiZM2dORbVoae5s/7y8PNOpUyfzzjvvmAEDBhBuysHV7f/mm2+aK6+80pw/f76yWrQ0V7f/0KFDTbdu3ZymjRw50iQlJVVon1ZXlnDz+OOPm5YtWzpN69u3r+nZs2cFdmYMu6XgsvPnz2vz5s3q3r27Y5qPj4+6d++udevWlWkd2dnZys3NVa1atSqqTctyd/tPnDhRderU0cMPP1wZbVqWO9v/008/VWJiooYOHaqoqChdffXVev7555Wfn19ZbVuGO9u/U6dO2rx5s2PX1f79+7V06VLdeuutldLz5WzdunVOPytJ6tmzZ5m/K9x12d04E+V38uRJ5efnKyoqyml6VFSUfvrppzKt44knnlC9evWK/NLj0tzZ/mvWrNG//vUvJScnV0KH1ubO9t+/f7+++eYb3XfffVq6dKn27t2rIUOGKDc3V+PHj6+Mti3Dne1/77336uTJk7r++utljFFeXp4eeeQRPfXUU5XR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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGwCAYAAACHJU4LAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA440lEQVR4nO3dd3xUVf7/8fekzKSQhIRQEggBCVIFIqBAXJBeXMuqiKCIfoVdiqyIomJZWHQFZXet2ECB3y5FV8SCCCoSFEV6kCYCoSkdSYeQcn5/uJllTCEzKXOTvJ6Px308mHvPPfOZO8Pcd+6ce6/NGGMEAABgQT7eLgAAAKA4BBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZft4uoCzy8/N19OhRhYSEyGazebscAABQCsYYpaenKzo6Wj4+JR8zqdJB5ejRo4qJifF2GQAAwANHjhxRo0aNSmxTpYNKSEiIpF9faGhoqJerAQAApZGWlqaYmBjnfrwkVTqoFPzcExoaSlABAKCKKc2wDQbTAgAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAFwfPZeuGLXt12ZrvlfDdbq09m+61WggqAADAKSsvX7du3afNaZnKys/XgXPZGrYtWfuyznulHoIKAABw2p6epZ+yc5Rnfn2cLynXGH1xOs0r9RBUAACAk7+PrdA8I8mviPmVgaACAACc2tUKUoeQQPn+97GvpNp+vrq+bm2v1ENQAQAATn4+Nr3TvpmGRdVRu1qB6h8ZpmUdm6u+w9879XjlWQEAgGWF+ftpZssYb5chiSMqAADAwggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsiwTVGbMmCGbzaYJEyZ4uxQAAGARlggqGzdu1BtvvKF27dp5uxQAAGAhXg8qGRkZuuOOOzR79myFh4d7uxwAAGAhXg8q48aN03XXXac+ffpcsm12drbS0tJcJgAAUH35efPJFy9erC1btmjjxo2laj99+nT99a9/reCqAACAVXjtiMqRI0d0//33a8GCBQoICCjVOpMnT1ZqaqpzOnLkSAVXCQAAvMlmjDHeeOIPPvhAf/jDH+Tr6+ucl5eXJ5vNJh8fH2VnZ7ssK0paWprCwsKUmpqq0NDQii4ZAACUA3f231776ad3797avn27y7x77rlHLVu21COPPHLJkAIAAKo/rwWVkJAQtW3b1mVecHCw6tSpU2g+AACombx+1g8AAEBxvHrWz28lJiZ6uwQAAGAhHFEBAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACW5efuCikpKVq6dKm+/vprHTp0SFlZWapbt67i4+PVv39/devWrSLqBAAANVCpj6gcPXpUI0eOVFRUlJ5++mmdO3dOHTp0UO/evdWoUSOtXr1affv2VevWrfXOO+9UZM0AAKCGKPURlfj4eI0YMUKbN29W69ati2xz7tw5ffDBB3rhhRd05MgRPfTQQyX2+dprr+m1117TwYMHJUlt2rTRX/7yFw0cOLD0rwAAAFRbNmOMKU3DM2fOqE6dOqXuuDTtP/74Y/n6+qp58+Yyxmj+/PmaOXOmtm7d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7K4H5P0kvdW2iVfqQfVW6sG0q1at0iOPPKLk5GT17dtXnTp1UnR0tAICAnT27Fnt2rVLa9eu1c6dO3XffffpscceK/IU5vLEYFoA8J7xuw5pc1qmGjrsmntFU9Xy8/V2Sagi3Nl/u33Wz9q1a/XOO+/o66+/1qFDh3Tu3DlFRkYqPj5e/fv31x133FFp11IhqAAAUPVUaFCxEoIKAABVT4VfmRYAAKAyuH168unTp/X2229r3bp1zivTNmjQQF27dtU999yjunXrlnuRAACgZnLriMrGjRt1+eWX66WXXlJYWJi6d++u7t27KywsTC+//LJatmypTZs2VVStAACghnFrjEqXLl3Uvn17vf7667LZbC7LjDEaPXq0vv/+e61bt67cCy0KY1QAAKh6KuwS+tu2bdO8efMKhRRJstlseuCBBxQfH+9etQAAAMVw66efBg0aaMOGDcUu37Bhg+rXr1/mogAAACQ3j6g89NBD+uMf/6jNmzerd+/ezlBy4sQJrVq1SrNnz9bf//73CikUAADUPG4FlXHjxikyMlLPP/+8Xn31VeXl5UmSfH191bFjR82bN0+33XZbhRQKAABqHo8v+JaTk6PTp09LkiIjI+Xv71+uhZUGg2kBAKh6Kmww7cX8/f0VFRXl6eoAAACXVK5Xpt2/f7969epVnl0CAIAarFyDSkZGhtasWVOeXQIAgBrMrZ9+XnrppRKX//zzz2UqBgAA4GJuBZUJEyYoKipKdru9yOUXLlwol6IAAAAkN4NKbGysnn322WJPQU5KSlLHjh3LpTAAAAC3xqh07NhRmzdvLna5zWaTh2c7AwAAFOLWEZVp06YpKyur2OWtW7fWgQMHylwUAACA5GZQad26dYnL/f39FRsbW6aCAAAACpTr6ckAAADlyaMr08bHx8tmsxWab7PZFBAQoLi4ON19993q2bNnif1Mnz5d77//vn744QcFBgaqW7duevbZZ9WiRQtPygIAANWMR0dUBgwYoOTkZAUHB6tnz57q2bOnatWqpf3796tz5846duyY+vTpow8//LDEftasWaNx48bpu+++0+eff66cnBz169dPmZmZHr0YAABQvXh0U8JRo0apcePGevLJJ13mP/300zp06JBmz56tKVOm6JNPPtGmTZtK3e+pU6dUr149rVmzRt27d79ke25KCABA1ePO/tujIyrvvvuuhg4dWmj+7bffrnfffVeSNHToUO3Zs8etflNTUyVJERERRS7Pzs5WWlqaywQAAKovj4JKQECAvv3220Lzv/32WwUEBEiS8vPznf8ujfz8fE2YMEEJCQlq27ZtkW2mT5+usLAw5xQTE+NJ+QAAoIrwaDDt+PHjNXr0aG3evFmdO3eWJG3cuFFz5szRY489JklauXKlOnToUOo+x40bpx07dmjt2rXFtpk8ebImTpzofJyWlkZYAQCgGvNojIokLViwQK+88orz550WLVpo/PjxGjZsmCTp3LlzzrOALuW+++7Thx9+qK+++kpNmzYtdQ2MUQEAoOpxZ//tcVApD8YYjR8/XkuXLlViYqKaN2/u1voEFQAAqh539t8e/fRTYPPmzdq9e7ckqU2bNoqPj3dr/XHjxmnhwoX68MMPFRISouPHj0uSwsLCFBgYWJbSAABANeDREZWTJ0/q9ttvV2JiomrXri1JSklJUc+ePbV48WLVrVu3dE9exEXjJGnu3Lm6++67L7k+R1QAAKh6Kvz05PHjxys9PV07d+7UL7/8ol9++UU7duxQWlqa/vznP5e6H2NMkVNpQgoAAKj+PDqiEhYWpi+++MJ5xk+BDRs2qF+/fkpJSSmv+krEERUAAKqeCj+ikp+fL39//0Lz/f39lZ+f70mXAAAAhXgUVHr16qX7779fR48edc77+eef9cADD6h3797lVhwAAKjZPAoqr7zyitLS0tSkSRM1a9ZMzZo1U9OmTZWWlqaXX365vGsEAAA1lEenJ8fExGjLli364osv9MMPP0iSWrVqpT59+pRrcQAAoGbz6gXfyorBtAAAVD0VcsG3l156qdQFuHOKMgAAQHFKfUSltPfgsdlsSk5OLlNRpcURFQAAqp4KOaJy4MCBIuevXbtWnTp1KtXNBwEAANzh0Vk/Fxs0aJDLacoAAADlpcxBpQqPxQUAABZX5qACAABQUcocVN544w3Vr1+/PGoBAABw4dEF3y42bNiw8qgDAACgEH76AQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAWAJ8+bNU+3atb1dRoVKTEyUzWZTSkpKufR38OBB2Ww2JSUlVUj/3nDttddqwoQJ3i4DFkJQAVAp7r77btlsNtlsNtntdsXFxWnatGnKzc31dmmFNGnSRC+88EK599utWzcdO3ZMYWFh5d53dfH+++/rqaeeKlXbigw1NptNH3zwQYX0fbG//e1v6tatm4KCgooN6gX/by6eFi9eXGK/N9xwgxo3bqyAgABFRUVp+PDhOnr0qEublStXqkuXLgoJCVHdunV1yy236ODBg87lW7duVXx8vGrVqqXrr79ev/zyi3NZbm6uOnbsqA0bNnj82kuLoAKg0gwYMEDHjh3T3r179eCDD2rq1KmaOXOmt8uqNHa7XQ0aNJDNZvN2KZYVERGhkJAQb5dRaS5cuKDBgwdrzJgxJbabO3eujh075pxuuummEtv37NlT7777rvbs2aMlS5Zo//79uvXWW53LDxw4oBtvvFG9evVSUlKSVq5cqdOnT+vmm292thk5cqR69eqlLVu2KDU1Vc8884xz2T/+8Q8lJCToqquu8uyFu8NUYampqUaSSU1N9XYpAC5hxIgR5sYbb3SZ17dvX9OlSxdjjDFz5841YWFhZsWKFaZly5YmODjY9O/f3xw9etRlndmzZ5uWLVsah8NhWrRoYWbNmuVcduDAASPJLFmyxFx77bUmMDDQtGvXznz77bcufbz33numdevWxm63m9jYWPP3v//duaxHjx5GksuUkZFhQkJCzH/+8x+XfpYuXWqCgoJMWlqa87kXLVpkunbtahwOh2nTpo1JTEx0tl+9erWRZM6ePeuct3btWtOjRw8TGBhoateubfr162d++eUXY4wxn376qUlISDBhYWEmIiLCXHfddWbfvn2FXu/WrVsL9V+amouSl5dnnn32WdOsWTNjt9tNTEyMefrpp53Lv//+e9OzZ08TEBBgIiIizKhRo0x6erpzecH7PHPmTNOgQQMTERFhxo4day5cuOBsM2vWLBMXF2ccDoepV6+eueWWW1y2//3333/JtiNGjCj0Ph04cMAYY8z27dvNgAEDTHBwsKlXr5658847zalTp1yeY/z48WbSpEkmPDzc1K9f30yZMsW5PDY21qXf2NjYIrdVeSr4/BdFklm6dGmZ+v/www+NzWZzvg//+c9/jJ+fn8nLy3O2+eijj1zaBAYGmt27dxtjjHn11VfNoEGDjDHG7N+/3zRv3rzYz1BpuLP/JqgAqBRFBZUbbrjBXHnllcaYX7+o/f39TZ8+fczGjRvN5s2bTatWrcywYcOc7f/973+bqKgos2TJEpOcnGyWLFliIiIizLx584wx/9txt2zZ0ixbtszs2bPH3HrrrSY2Ntbk5OQYY4zZtGmT8fHxMdOmTTN79uwxc+fONYGBgWbu3LnGGGPOnDljGjVqZKZNm2aOHTtmjh07ZowxZtSoUc4v6ovrv+uuu1yeu1GjRua9994zu3btMiNHjjQhISHm9OnTxpjCQWXr1q3G4XCYMWPGmKSkJLNjxw7z8ssvO3eq7733nlmyZInZu3ev2bp1q7n++uvNFVdc4dy5lBRUSlNzUR5++GETHh5u5s2bZ/bt22e+/vprM3v2bGOMMRkZGSYqKsrcfPPNZvv27WbVqlWmadOmZsSIES7vc2hoqBk9erTZvXu3+fjjj01QUJB58803jTHGbNy40fj6+pqFCxeagwcPmi1btpgXX3zRuf7FQaWktikpKaZr165m1KhRzvcpNzfXnD171tStW9dMnjzZ7N6922zZssX07dvX9OzZ0+U5QkNDzdSpU82PP/5o5s+fb2w2m/nss8+MMcacPHnSSDJz5841x44dMydPnix2e7Vu3doEBwcXOw0YMKDYdS92qaASHR1t6tSpYzp37mzeeustk5+fX6p+jfn1M33bbbeZhIQE57zk5GRjt9vNnDlzTG5urklJSTGDBw82ffv2dbbp0qWLeemll0xOTo655ZZbzKOPPmqM+fUPjLIGJ4IKAMu5OKjk5+ebzz//3DgcDvPQQw8ZY379opbkcsRg1qxZpn79+s7HzZo1MwsXLnTp96mnnjJdu3Y1xvxvxz1nzhzn8p07dxpJzr8Mhw0b5vJlbIwxkyZNMq1bt3Y+jo2NNc8//7xLm/Xr1xtfX1/nEZ4TJ04YPz8/5xGTgueeMWOGc52cnBzTqFEj8+yzzxpjCgeJoUOHuuw8LuXUqVNGktm+fbvLcxYXVC5V82+lpaUZh8PhDCa/9eabb5rw8HCTkZHhnPfJJ58YHx8fc/z4cWPMr+9zbGysyc3NdbYZPHiwGTJkiDHGmCVLlpjQ0NBi/xq/OKi407bAU089Zfr16+cy78iRI0aS2bNnj3O9a665xqVN586dzSOPPOJ8XNqjGAcPHjR79+4tdvrpp58u2YcxJQeVadOmmbVr15otW7aYGTNmGIfD4RLuivPwww+boKAgI8l06dLFGZgLJCYmmnr16hlfX18jyXTt2tXlaN+OHTtM9+7dTePGjc3QoUNNamqq+X//7/+ZG2+80fz000+mX79+plmzZubxxx8v1Wu8mDv7b8aoAKg0y5YtU61atRQQEKCBAwdqyJAhmjp1qnN5UFCQmjVr5nwcFRWlkydPSpIyMzO1f/9+3XvvvapVq5Zzevrpp7V//36X52nXrp1LH5Kc/ezevVsJCQku7RMSErR3717l5eUVW/tVV12lNm3aaP78+ZKkf//734qNjVX37t1d2nXt2tX5bz8/P3Xq1Em7d+8uss+kpCT17t272Ofcu3evhg4dqssuu0yhoaFq0qSJJOnw4cPFruNJzQV2796t7OzsYmvavXu32rdvr+DgYOe8hIQE5efna8+ePc55bdq0ka+vr/Pxxe9j3759FRsbq8suu0zDhw/XggULlJWVVeTzudO2wLZt27R69WqXz0jLli0lyeVzcvFn5Lc1uiM2NlZxcXHFTg0bNnS7z9968sknlZCQoPj4eD3yyCN6+OGHSzW2a9KkSdq6das+++wz+fr66q677pIxRpJ0/PhxjRo1SiNGjNDGjRu1Zs0a2e123Xrrrc42bdq00Zo1a3To0CEtXLhQOTk5mjJlil555RWNHz9e3bp107Zt2/T+++/r448/LvPrLA5BBUCl6dmzp5KSkrR3716dO3dO8+fPd9np+fv7u7S32WzOL82MjAxJ0uzZs5WUlOScduzYoe+++85lvYv7KRi4mp+fX+b6R44cqXnz5kn6dXDjPffcU6aBsYGBgSUuLzjTYvbs2Vq/fr3Wr18v6dcBmBVR86XqKa2i3seC7R8SEqItW7Zo0aJFioqK0l/+8he1b9++yFOq3WlbICMjQ9dff73LZ6TgM3dxQCupRne0adPGJRT9dho4cKDbfV7K1VdfrZ9++knZ2dkltouMjNTll1+uvn37avHixVq+fLnz/8qsWbMUFham5557TvHx8erevbv+/e9/a9WqVc7P2W9NnDhREyZMUKNGjZSYmKjBgwcrODhY1113nRITE8v7ZToRVABUmuDgYMXFxalx48by8/Nza9369esrOjpaycnJhf5qbdq0aan7adWqlb755huXed98840uv/xy51EAu91e5NGVO++8U4cOHdJLL72kXbt2acSIEYXaXByacnNztXnzZrVq1arIWtq1a6dVq1YVuezMmTPas2ePnnji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NGiQWbt2rTlw4IBJTEw0SUlJlVx59eDu9l+wYIFxOBxmwYIF5sCBA2blypUmKirKPPDAA5VcefWwfPly8/jjj5v333/fSDJLly4tsX1ycrIJCgoyEydONLt27TIvv/yy8fX1NStWrKjQOgkqMFdddZUZN26c83FeXp6Jjo4206dPL9X6ubm5JiQkxMyfP7+iSqzWPNn+ubm5plu3bmbOnDlmxIgRBBUPubvtX3vtNXPZZZeZCxcuVFaJ1Zq723/cuHGmV69eLvMmTpxoEhISKrTOmqA0QeXhhx82bdq0cZk3ZMgQ079//wqszBh++qnhLly4oM2bN6tPnz7OeT4+PurTp4/WrVtXqj6ysrKUk5OjiIiIiiqz2vJ0+0+bNk316tXTvffeWxllVkuebPuPPvpIXbt21bhx41S/fn21bdtWzzzzjPLy8iqr7GrDk+3frVs3bd682fnzUHJyspYvX65BgwZVSs013bp161zeL0nq379/qfcVnqrSNyVE2Z0+fVp5eXmqX7++y/z69evrhx9+KFUfjzzyiKKjowt9gHFpnmz/tWvX6q233lJSUlIlVFh9ebLtk5OT9eWXX+qOO+7Q8uXLtW/fPo0dO1Y5OTmaMmVKZZRdbXiy/YcNG6bTp0/rmmuukTFGubm5Gj16tB577LHKKLnGO378eJHvV1pams6dO6fAwMAKeV6OqKBMZsyYocWLF2vp0qUKCAjwdjnVXnp6uoYPH67Zs2crMjLS2+XUOPn5+apXr57efPNNdezYUUOGDNHjjz+u119/3dul1QiJiYl65pln9Oqrr2rLli16//339cknn+ipp57ydmmoQBxRqeEiIyPl6+urEydOuMw/ceKEGjRoUOK6f//73zVjxgx98cUXateuXUWWWW25u/3379+vgwcP6vrrr3fOy8/PlyT5+flpz549atasWcUWXU148tmPioqSv7+/fH19nfNatWql48eP68KFC7Lb7RVac3XiyfZ/8sknNXz4cI0cOVKSdMUVVygzM1N//OMf9fjjj8vHh7+9K1KDBg2KfL9CQ0Mr7GiKxBGVGs9ut6tjx45atWqVc15+fr5WrVqlrl27Frvec889p6eeekorVqxQp06dKqPUasnd7d+yZUtt375dSUlJzumGG25Qz549lZSUpJiYmMosv0rz5LOfkJCgffv2OcOhJP3444+KiooipLjJk+2flZVVKIwUhEbDbesqXNeuXV3eL0n6/PPPS9xXlIsKHaqLKmHx4sXG4XCYefPmmV27dpk//vGPpnbt2ub48ePGGGOGDx9uHn30UWf7GTNmGLvdbt577z1z7Ngx55Senu6tl1Clubv9f4uzfjzn7rY/fPiwCQkJMffdd5/Zs2ePWbZsmalXr555+umnvfUSqjR3t/+UKVNMSEiIWbRokUlOTjafffaZadasmbntttu89RKqtPT0dLN161azdetWI8n885//NFu3bjWHDh0yxhjz6KOPmuHDhzvbF5yePGnSJLN7924za9YsTk9G5Xn55ZdN48aNjd1uN1dddZX57rvvnMt69OhhRowY4XwcGxtrJBWapkyZUvmFVxPubP/fIqiUjbvb/ttvvzVXX321cTgc5rLLLjN/+9vfTG5ubiVXXX24s/1zcnLM1KlTTbNmzUxAQICJiYkxY8eONWfPnq38wquB1atXF/ldXrDNR4wYYXr06FFonQ4dOhi73W4uu+wyM3fu3Aqv02YMx8sAAIA1MUYFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFgKX1799fvr6+2rhxY6Fld999t2w2m2w2m+x2u+Li4jRt2jTl5uZ6oVIAFYGgAsCyDh8+rG+//Vb33Xef3n777SLbDBgwQMeOHdPevXv14IMPaurUqZo5c2YlVwqgohBUAFS4a6+9VuPHj9eECRMUHh6u+vXra/bs2crMzNQ999yjkJAQxcXF6dNPP3VZb+7cufr973+vMWPGaNGiRTp37lyhvh0Ohxo0aKDY2FiNGTNGffr00UcffVRZLw1ABSOoAKgU8+fPV2RkpDZs2KDx48drzJgxGjx4sLp166YtW7aoX79+Gj58uLKysiRJxhjNnTtXd955p1q2bKm4uDi99957l3yewMBAXbhwoaJfDoBKQlABUCnat2+vJ554Qs2bN9fkyZMVEBCgyMhIjRo1Ss2bN9df/vIXnTlzRt9//70k6YsvvlBWVpb69+8vSbrzzjv11ltvFdu/MUZffPGFVq5cqV69elXKawJQ8QgqACpFu3btnP/29fVVnTp1dMUVVzjn1a9fX5J08uRJSdLbb7+tIUOGyM/PT5I0dOhQffPNN9q/f79Lv8uWLVOtWrUUEBCggQMHasiQIZo6dWoFvxoAlYWgAqBS+Pv7uzy22Wwu82w2myQpPz9fv/zyi5YuXapXX31Vfn5+8vPzU8OGDZWbm1toUG3Pnj2VlJSkvXv36ty5c5o/f76Cg4Mr/gUBqBR+3i4AAH5rwYIFatSokT744AOX+Z999pn+8Y9/aNq0afL19ZUkBQcHKy4uzgtVAqgMBBUAlvPWW2/p1ltvVdu2bV3mx8TEaPLkyVqxYoWuu+46L1UHoDLx0w8AS9m/f7+2bdumW265pdCysLAw9e7du8RBtQCqF5sxxni7CAAAgKJwRAUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFjW/wdjHVoMVQbXvwAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -2990,7 +3021,7 @@ ], "metadata": { "kernelspec": { - "display_name": "map_benchmark", + "display_name": "copairs", "language": "python", "name": "python3" }, @@ -3004,7 +3035,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.9.19" } }, "nbformat": 4, From 8668420b2605b4364bc4c8cd7a8d0d9a5817ffe8 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:10:13 -0500 Subject: [PATCH 12/21] chore: bump version to 0.4.4 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c74d308..f11b0ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "copairs" -version = "0.4.3" +version = "0.4.4" description = "Find pairs and compute metrics between them" readme = "README.md" requires-python = ">=3.8" From 28fcc4a7b49e92893819816fba6ca4373538fc66 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:19:04 -0500 Subject: [PATCH 13/21] chore: ruff format demo --- examples/F1.large.jpg | Bin 0 -> 178450 bytes examples/mAP_demo.ipynb | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 examples/F1.large.jpg diff --git a/examples/F1.large.jpg b/examples/F1.large.jpg new file mode 100644 index 0000000000000000000000000000000000000000..82c2023ae39d50dd9ffc24f0f7d205519f9956b4 GIT binary patch literal 178450 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À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 Wt;5;@AapSLKkPvNOK9@f!v6wXvtcm+ literal 0 HcmV?d00001 diff --git a/examples/mAP_demo.ipynb b/examples/mAP_demo.ipynb index 1d98b24..edd99ec 100644 --- a/examples/mAP_demo.ipynb +++ b/examples/mAP_demo.ipynb @@ -1844,7 +1844,11 @@ "plt.ylabel(\"-log10(p-value)\")\n", "plt.axhline(-np.log10(0.05), color=\"black\", linestyle=\"--\")\n", "plt.text(\n", - " 0.5, 1.5, f\"Phenotypically active = {100*active_ratio:.2f}%\", va=\"center\", ha=\"left\"\n", + " 0.5,\n", + " 1.5,\n", + " f\"Phenotypically active = {100 * active_ratio:.2f}%\",\n", + " va=\"center\",\n", + " ha=\"left\",\n", ")\n", "plt.show()" ] @@ -2970,7 +2974,7 @@ "plt.text(\n", " 0.5,\n", " 1.5,\n", - " f\"Phenotypically consistent = {100*consistent_ratio:.2f}%\",\n", + " f\"Phenotypically consistent = {100 * consistent_ratio:.2f}%\",\n", " va=\"center\",\n", " ha=\"left\",\n", ")\n", From fb0898c329b60f89afb4e0d6c80836ea970206fe Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Mon, 3 Feb 2025 00:36:20 -0500 Subject: [PATCH 14/21] feat(matching): add func for assigning reference index col closes cytomining/copairs#75 --- examples/mAP_demo.ipynb | 655 ++++++---------------------------------- src/copairs/matching.py | 17 ++ 2 files changed, 111 insertions(+), 561 deletions(-) diff --git a/examples/mAP_demo.ipynb b/examples/mAP_demo.ipynb index edd99ec..808116b 100644 --- a/examples/mAP_demo.ipynb +++ b/examples/mAP_demo.ipynb @@ -10,7 +10,8 @@ "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "\n", - "from copairs import map" + "from copairs import map\n", + "from copairs.matching import assign_reference_index" ] }, { @@ -630,484 +631,16 @@ "cell_type": "code", "execution_count": 6, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "

\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Metadata_reference_indexMetadata_broad_sampleMetadata_mg_per_mlMetadata_mmoles_per_literMetadata_pert_idMetadata_pert_mfc_idMetadata_pert_wellMetadata_broad_sample_typeMetadata_pert_typeMetadata_broad_id...Nuclei_Texture_InverseDifferenceMoment_AGP_5_0Nuclei_Texture_InverseDifferenceMoment_DNA_20_0Nuclei_Texture_InverseDifferenceMoment_ER_5_0Nuclei_Texture_InverseDifferenceMoment_Mito_10_0Nuclei_Texture_InverseDifferenceMoment_Mito_5_0Nuclei_Texture_SumAverage_RNA_5_0Nuclei_Texture_SumEntropy_DNA_10_0Nuclei_Texture_SumEntropy_DNA_20_0Nuclei_Texture_SumEntropy_DNA_5_0Nuclei_Texture_Variance_RNA_10_0
00DMSO0.0000000.000000NaNNaNA01controlcontrolNaN...-1.3544-1.077702.26020-0.377010-0.0658402.123602.87402.875002.3047-0.92358
11DMSO0.0000000.000000NaNNaNA02controlcontrolNaN...-2.3840-0.734401.12090-0.182500-0.0614500.669852.39192.352301.8672-0.11820
22DMSO0.0000000.000000NaNNaNA03controlcontrolNaN...-1.9493-0.361480.440500.3266600.5472000.250151.22710.778471.0651-0.44810
33DMSO0.0000000.000000NaNNaNA04controlcontrolNaN...-2.2909-0.463800.964341.1322000.7535000.314031.43841.481101.2943-0.83810
44DMSO0.0000000.000000NaNNaNA05controlcontrolNaN...-1.8955-1.053501.648400.0577810.0702291.609901.12960.902131.10160.53225
..................................................................
379-1BRD-K82746043-001-15-13.2487003.333300BRD-K82746043BRD-K82746043-001-15-1P20trttrtBRD-K82746043...-6.15221.814101.54220-1.874700-1.1339001.57540-3.0962-3.25160-2.76831.40170
380-1BRD-K82746043-001-15-11.0829001.111100BRD-K82746043BRD-K82746043-001-15-1P21trttrtBRD-K82746043...-5.15861.505801.68420-1.126400-1.0666001.24740-1.5305-1.79020-1.24741.17600
381-1BRD-K82746043-001-15-10.3609700.370370BRD-K82746043BRD-K82746043-001-15-1P22trttrtBRD-K82746043...-5.94751.421001.51020-1.103600-1.6665001.19840-2.6086-2.97620-2.00260.91557
382-1BRD-K82746043-001-15-10.1203200.123460BRD-K82746043BRD-K82746043-001-15-1P23trttrtBRD-K82746043...-8.44082.996202.55230-2.275200-1.7835002.49200-4.3964-4.19030-3.83601.02240
383-1BRD-K82746043-001-15-10.0401080.041152BRD-K82746043BRD-K82746043-001-15-1P24trttrtBRD-K82746043...-7.95102.557303.05790-1.466300-1.6738001.99540-4.2176-4.49940-3.49221.01170
\n", - "

384 rows × 508 columns

\n", - "
" - ], - "text/plain": [ - " Metadata_reference_index Metadata_broad_sample Metadata_mg_per_ml \\\n", - "0 0 DMSO 0.000000 \n", - "1 1 DMSO 0.000000 \n", - "2 2 DMSO 0.000000 \n", - "3 3 DMSO 0.000000 \n", - "4 4 DMSO 0.000000 \n", - ".. ... ... ... \n", - "379 -1 BRD-K82746043-001-15-1 3.248700 \n", - "380 -1 BRD-K82746043-001-15-1 1.082900 \n", - "381 -1 BRD-K82746043-001-15-1 0.360970 \n", - "382 -1 BRD-K82746043-001-15-1 0.120320 \n", - "383 -1 BRD-K82746043-001-15-1 0.040108 \n", - "\n", - " Metadata_mmoles_per_liter Metadata_pert_id Metadata_pert_mfc_id \\\n", - "0 0.000000 NaN NaN \n", - "1 0.000000 NaN NaN \n", - "2 0.000000 NaN NaN \n", - "3 0.000000 NaN NaN \n", - "4 0.000000 NaN NaN \n", - ".. ... ... ... \n", - "379 3.333300 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "380 1.111100 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "381 0.370370 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "382 0.123460 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "383 0.041152 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "\n", - " Metadata_pert_well Metadata_broad_sample_type Metadata_pert_type \\\n", - "0 A01 control control \n", - "1 A02 control control \n", - "2 A03 control control \n", - "3 A04 control control \n", - "4 A05 control control \n", - ".. ... ... ... \n", - "379 P20 trt trt \n", - "380 P21 trt trt \n", - "381 P22 trt trt \n", - "382 P23 trt trt \n", - "383 P24 trt trt \n", - "\n", - " Metadata_broad_id ... Nuclei_Texture_InverseDifferenceMoment_AGP_5_0 \\\n", - "0 NaN ... -1.3544 \n", - "1 NaN ... -2.3840 \n", - "2 NaN ... -1.9493 \n", - "3 NaN ... -2.2909 \n", - "4 NaN ... -1.8955 \n", - ".. ... ... ... \n", - "379 BRD-K82746043 ... -6.1522 \n", - "380 BRD-K82746043 ... -5.1586 \n", - "381 BRD-K82746043 ... -5.9475 \n", - "382 BRD-K82746043 ... -8.4408 \n", - "383 BRD-K82746043 ... -7.9510 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_DNA_20_0 \\\n", - "0 -1.07770 \n", - "1 -0.73440 \n", - "2 -0.36148 \n", - "3 -0.46380 \n", - "4 -1.05350 \n", - ".. ... \n", - "379 1.81410 \n", - "380 1.50580 \n", - "381 1.42100 \n", - "382 2.99620 \n", - "383 2.55730 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_ER_5_0 \\\n", - "0 2.26020 \n", - "1 1.12090 \n", - "2 0.44050 \n", - "3 0.96434 \n", - "4 1.64840 \n", - ".. ... \n", - "379 1.54220 \n", - "380 1.68420 \n", - "381 1.51020 \n", - "382 2.55230 \n", - "383 3.05790 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_Mito_10_0 \\\n", - "0 -0.377010 \n", - "1 -0.182500 \n", - "2 0.326660 \n", - "3 1.132200 \n", - "4 0.057781 \n", - ".. ... \n", - "379 -1.874700 \n", - "380 -1.126400 \n", - "381 -1.103600 \n", - "382 -2.275200 \n", - "383 -1.466300 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_Mito_5_0 \\\n", - "0 -0.065840 \n", - "1 -0.061450 \n", - "2 0.547200 \n", - "3 0.753500 \n", - "4 0.070229 \n", - ".. ... \n", - "379 -1.133900 \n", - "380 -1.066600 \n", - "381 -1.666500 \n", - "382 -1.783500 \n", - "383 -1.673800 \n", - "\n", - " Nuclei_Texture_SumAverage_RNA_5_0 Nuclei_Texture_SumEntropy_DNA_10_0 \\\n", - "0 2.12360 2.8740 \n", - "1 0.66985 2.3919 \n", - "2 0.25015 1.2271 \n", - "3 0.31403 1.4384 \n", - "4 1.60990 1.1296 \n", - ".. ... ... \n", - "379 1.57540 -3.0962 \n", - "380 1.24740 -1.5305 \n", - "381 1.19840 -2.6086 \n", - "382 2.49200 -4.3964 \n", - "383 1.99540 -4.2176 \n", - "\n", - " Nuclei_Texture_SumEntropy_DNA_20_0 Nuclei_Texture_SumEntropy_DNA_5_0 \\\n", - "0 2.87500 2.3047 \n", - "1 2.35230 1.8672 \n", - "2 0.77847 1.0651 \n", - "3 1.48110 1.2943 \n", - "4 0.90213 1.1016 \n", - ".. ... ... \n", - "379 -3.25160 -2.7683 \n", - "380 -1.79020 -1.2474 \n", - "381 -2.97620 -2.0026 \n", - "382 -4.19030 -3.8360 \n", - "383 -4.49940 -3.4922 \n", - "\n", - " Nuclei_Texture_Variance_RNA_10_0 \n", - "0 -0.92358 \n", - "1 -0.11820 \n", - "2 -0.44810 \n", - "3 -0.83810 \n", - "4 0.53225 \n", - ".. ... \n", - "379 1.40170 \n", - "380 1.17600 \n", - "381 0.91557 \n", - "382 1.02240 \n", - "383 1.01170 \n", - "\n", - "[384 rows x 508 columns]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "df_activity = df.copy()\n", - "# make deafult value equal to row index\n", - "df_activity[\"Metadata_reference_index\"] = df_activity.index\n", - "# make index equal to -1 for all treatment replicates (non-DMSO)\n", - "df_activity.loc[df[\"Metadata_broad_sample\"] != \"DMSO\", \"Metadata_reference_index\"] = -1\n", - "# now all treatment replicates equal -1 in the index column, except for DMSO replicates\n", - "df_activity.insert(\n", - " 0, \"Metadata_reference_index\", df_activity.pop(\"Metadata_reference_index\")\n", - ")\n", - "df_activity" + "reference_col = \"Metadata_reference_index\"\n", + "\n", + "df_activity = assign_reference_index(\n", + " df,\n", + " \"Metadata_broad_sample == 'DMSO'\", # condition to get reference profiles (neg controls for activity)\n", + " reference_col=reference_col,\n", + " default_value=-1,\n", + ")" ] }, { @@ -1132,12 +665,12 @@ "outputs": [], "source": [ "# positive pairs are replicates of the same treatment\n", - "pos_sameby = [\"Metadata_broad_sample\", \"Metadata_reference_index\"]\n", + "pos_sameby = [\"Metadata_broad_sample\", reference_col]\n", "pos_diffby = []\n", "\n", "neg_sameby = []\n", "# negative pairs are replicates of different treatments\n", - "neg_diffby = [\"Metadata_broad_sample\", \"Metadata_reference_index\"]" + "neg_diffby = [\"Metadata_broad_sample\", reference_col]" ] }, { @@ -1157,7 +690,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "4af9b0bae8b94951aedb5a11e4cb980b", + "model_id": "51e0cabc26764909bf69fefe2213491b", "version_major": 2, "version_minor": 0 }, @@ -1171,7 +704,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e2248bbf1ad34dfdb1a07fec3b4b8cfb", + "model_id": "c498f5cd080e4b1193c1dcb7a25b2b2b", "version_major": 2, "version_minor": 0 }, @@ -1211,7 +744,6 @@ " \n", " \n", " \n", - " Metadata_reference_index\n", " Metadata_broad_sample\n", " Metadata_mg_per_ml\n", " Metadata_mmoles_per_liter\n", @@ -1226,6 +758,7 @@ " Metadata_target\n", " Metadata_broad_date\n", " Metadata_Well\n", + " Metadata_reference_index\n", " n_pos_pairs\n", " n_total_pairs\n", " average_precision\n", @@ -1234,7 +767,6 @@ " \n", " \n", " 6\n", - " -1\n", " BRD-K74363950-004-01-0\n", " 5.655600\n", " 10.000000\n", @@ -1249,13 +781,13 @@ " CHRM1|CHRM2|CHRM3|CHRM4|CHRM5\n", " broad_id_20170327\n", " A07\n", + " -1\n", " 5\n", " 29\n", " 0.325013\n", " \n", " \n", " 7\n", - " -1\n", " BRD-K74363950-004-01-0\n", " 1.885200\n", " 3.333300\n", @@ -1270,13 +802,13 @@ " CHRM1|CHRM2|CHRM3|CHRM4|CHRM5\n", " broad_id_20170327\n", " A08\n", + " -1\n", " 5\n", " 29\n", " 0.513889\n", " \n", " \n", " 8\n", - " -1\n", " BRD-K74363950-004-01-0\n", " 0.628400\n", " 1.111100\n", @@ -1291,13 +823,13 @@ " CHRM1|CHRM2|CHRM3|CHRM4|CHRM5\n", " broad_id_20170327\n", " A09\n", + " -1\n", " 5\n", " 29\n", " 0.727778\n", " \n", " \n", " 9\n", - " -1\n", " BRD-K74363950-004-01-0\n", " 0.209470\n", " 0.370370\n", @@ -1312,13 +844,13 @@ " CHRM1|CHRM2|CHRM3|CHRM4|CHRM5\n", " broad_id_20170327\n", " A10\n", + " -1\n", " 5\n", " 29\n", " 0.783333\n", " \n", " \n", " 10\n", - " -1\n", " BRD-K74363950-004-01-0\n", " 0.069823\n", " 0.123460\n", @@ -1333,6 +865,7 @@ " CHRM1|CHRM2|CHRM3|CHRM4|CHRM5\n", " broad_id_20170327\n", " A11\n", + " -1\n", " 5\n", " 29\n", " 0.900000\n", @@ -1360,7 +893,6 @@ " \n", " \n", " 379\n", - " -1\n", " BRD-K82746043-001-15-1\n", " 3.248700\n", " 3.333300\n", @@ -1375,13 +907,13 @@ " BCL2|BCL2L1|BCL2L2\n", " broad_id_20170327\n", " P20\n", + " -1\n", " 5\n", " 29\n", " 1.000000\n", " \n", " \n", " 380\n", - " -1\n", " BRD-K82746043-001-15-1\n", " 1.082900\n", " 1.111100\n", @@ -1396,13 +928,13 @@ " BCL2|BCL2L1|BCL2L2\n", " broad_id_20170327\n", " P21\n", + " -1\n", " 5\n", " 29\n", " 0.966667\n", " \n", " \n", " 381\n", - " -1\n", " BRD-K82746043-001-15-1\n", " 0.360970\n", " 0.370370\n", @@ -1417,13 +949,13 @@ " BCL2|BCL2L1|BCL2L2\n", " broad_id_20170327\n", " P22\n", + " -1\n", " 5\n", " 29\n", " 0.942857\n", " \n", " \n", " 382\n", - " -1\n", " BRD-K82746043-001-15-1\n", " 0.120320\n", " 0.123460\n", @@ -1438,13 +970,13 @@ " BCL2|BCL2L1|BCL2L2\n", " broad_id_20170327\n", " P23\n", + " -1\n", " 5\n", " 29\n", " 1.000000\n", " \n", " \n", " 383\n", - " -1\n", " BRD-K82746043-001-15-1\n", " 0.040108\n", " 0.041152\n", @@ -1459,6 +991,7 @@ " BCL2|BCL2L1|BCL2L2\n", " broad_id_20170327\n", " P24\n", + " -1\n", " 5\n", " 29\n", " 1.000000\n", @@ -1469,57 +1002,57 @@ "" ], "text/plain": [ - " Metadata_reference_index Metadata_broad_sample Metadata_mg_per_ml \\\n", - "6 -1 BRD-K74363950-004-01-0 5.655600 \n", - "7 -1 BRD-K74363950-004-01-0 1.885200 \n", - "8 -1 BRD-K74363950-004-01-0 0.628400 \n", - "9 -1 BRD-K74363950-004-01-0 0.209470 \n", - "10 -1 BRD-K74363950-004-01-0 0.069823 \n", - ".. ... ... ... \n", - "379 -1 BRD-K82746043-001-15-1 3.248700 \n", - "380 -1 BRD-K82746043-001-15-1 1.082900 \n", - "381 -1 BRD-K82746043-001-15-1 0.360970 \n", - "382 -1 BRD-K82746043-001-15-1 0.120320 \n", - "383 -1 BRD-K82746043-001-15-1 0.040108 \n", + " Metadata_broad_sample Metadata_mg_per_ml Metadata_mmoles_per_liter \\\n", + "6 BRD-K74363950-004-01-0 5.655600 10.000000 \n", + "7 BRD-K74363950-004-01-0 1.885200 3.333300 \n", + "8 BRD-K74363950-004-01-0 0.628400 1.111100 \n", + "9 BRD-K74363950-004-01-0 0.209470 0.370370 \n", + "10 BRD-K74363950-004-01-0 0.069823 0.123460 \n", + ".. ... ... ... \n", + "379 BRD-K82746043-001-15-1 3.248700 3.333300 \n", + "380 BRD-K82746043-001-15-1 1.082900 1.111100 \n", + "381 BRD-K82746043-001-15-1 0.360970 0.370370 \n", + "382 BRD-K82746043-001-15-1 0.120320 0.123460 \n", + "383 BRD-K82746043-001-15-1 0.040108 0.041152 \n", "\n", - " Metadata_mmoles_per_liter Metadata_pert_id Metadata_pert_mfc_id \\\n", - "6 10.000000 BRD-K74363950 BRD-K74363950-004-01-0 \n", - "7 3.333300 BRD-K74363950 BRD-K74363950-004-01-0 \n", - "8 1.111100 BRD-K74363950 BRD-K74363950-004-01-0 \n", - "9 0.370370 BRD-K74363950 BRD-K74363950-004-01-0 \n", - "10 0.123460 BRD-K74363950 BRD-K74363950-004-01-0 \n", - ".. ... ... ... \n", - "379 3.333300 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "380 1.111100 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "381 0.370370 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "382 0.123460 BRD-K82746043 BRD-K82746043-001-15-1 \n", - "383 0.041152 BRD-K82746043 BRD-K82746043-001-15-1 \n", + " Metadata_pert_id Metadata_pert_mfc_id Metadata_pert_well \\\n", + "6 BRD-K74363950 BRD-K74363950-004-01-0 A07 \n", + "7 BRD-K74363950 BRD-K74363950-004-01-0 A08 \n", + "8 BRD-K74363950 BRD-K74363950-004-01-0 A09 \n", + "9 BRD-K74363950 BRD-K74363950-004-01-0 A10 \n", + "10 BRD-K74363950 BRD-K74363950-004-01-0 A11 \n", + ".. ... ... ... \n", + "379 BRD-K82746043 BRD-K82746043-001-15-1 P20 \n", + "380 BRD-K82746043 BRD-K82746043-001-15-1 P21 \n", + "381 BRD-K82746043 BRD-K82746043-001-15-1 P22 \n", + "382 BRD-K82746043 BRD-K82746043-001-15-1 P23 \n", + "383 BRD-K82746043 BRD-K82746043-001-15-1 P24 \n", "\n", - " Metadata_pert_well Metadata_broad_sample_type Metadata_pert_type \\\n", - "6 A07 trt trt \n", - "7 A08 trt trt \n", - "8 A09 trt trt \n", - "9 A10 trt trt \n", - "10 A11 trt trt \n", - ".. ... ... ... \n", - "379 P20 trt trt \n", - "380 P21 trt trt \n", - "381 P22 trt trt \n", - "382 P23 trt trt \n", - "383 P24 trt trt \n", + " Metadata_broad_sample_type Metadata_pert_type Metadata_broad_id \\\n", + "6 trt trt BRD-K74363950 \n", + "7 trt trt BRD-K74363950 \n", + "8 trt trt BRD-K74363950 \n", + "9 trt trt BRD-K74363950 \n", + "10 trt trt BRD-K74363950 \n", + ".. ... ... ... \n", + "379 trt trt BRD-K82746043 \n", + "380 trt trt BRD-K82746043 \n", + "381 trt trt BRD-K82746043 \n", + "382 trt trt BRD-K82746043 \n", + "383 trt trt BRD-K82746043 \n", "\n", - " Metadata_broad_id Metadata_InChIKey14 Metadata_moa \\\n", - "6 BRD-K74363950 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", - "7 BRD-K74363950 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", - "8 BRD-K74363950 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", - "9 BRD-K74363950 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", - "10 BRD-K74363950 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", - ".. ... ... ... \n", - "379 BRD-K82746043 JLYAXFNOILIKPP BCL inhibitor \n", - "380 BRD-K82746043 JLYAXFNOILIKPP BCL inhibitor \n", - "381 BRD-K82746043 JLYAXFNOILIKPP BCL inhibitor \n", - "382 BRD-K82746043 JLYAXFNOILIKPP BCL inhibitor \n", - "383 BRD-K82746043 JLYAXFNOILIKPP BCL inhibitor \n", + " Metadata_InChIKey14 Metadata_moa \\\n", + "6 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", + "7 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", + "8 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", + "9 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", + "10 ASMXXROZKSBQIH acetylcholine receptor antagonist \n", + ".. ... ... \n", + "379 JLYAXFNOILIKPP BCL inhibitor \n", + "380 JLYAXFNOILIKPP BCL inhibitor \n", + "381 JLYAXFNOILIKPP BCL inhibitor \n", + "382 JLYAXFNOILIKPP BCL inhibitor \n", + "383 JLYAXFNOILIKPP BCL inhibitor \n", "\n", " Metadata_target Metadata_broad_date Metadata_Well \\\n", "6 CHRM1|CHRM2|CHRM3|CHRM4|CHRM5 broad_id_20170327 A07 \n", @@ -1534,18 +1067,18 @@ "382 BCL2|BCL2L1|BCL2L2 broad_id_20170327 P23 \n", "383 BCL2|BCL2L1|BCL2L2 broad_id_20170327 P24 \n", "\n", - " n_pos_pairs n_total_pairs average_precision \n", - "6 5 29 0.325013 \n", - "7 5 29 0.513889 \n", - "8 5 29 0.727778 \n", - "9 5 29 0.783333 \n", - "10 5 29 0.900000 \n", - ".. ... ... ... \n", - "379 5 29 1.000000 \n", - "380 5 29 0.966667 \n", - "381 5 29 0.942857 \n", - "382 5 29 1.000000 \n", - "383 5 29 1.000000 \n", + " Metadata_reference_index n_pos_pairs n_total_pairs average_precision \n", + "6 -1 5 29 0.325013 \n", + "7 -1 5 29 0.513889 \n", + "8 -1 5 29 0.727778 \n", + "9 -1 5 29 0.783333 \n", + "10 -1 5 29 0.900000 \n", + ".. ... ... ... ... \n", + "379 -1 5 29 1.000000 \n", + "380 -1 5 29 0.966667 \n", + "381 -1 5 29 0.942857 \n", + "382 -1 5 29 1.000000 \n", + "383 -1 5 29 1.000000 \n", "\n", "[360 rows x 18 columns]" ] @@ -1583,7 +1116,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "1f294742f68b4481adae455126b9168e", + "model_id": "893c58d190a84aa5953e1211feb581b7", "version_major": 2, "version_minor": 0 }, @@ -1597,7 +1130,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f993a3498f8a486ca65810bc41281a12", + "model_id": "67fdff1eb18e45bdb45a314a10ed9c18", "version_major": 2, "version_minor": 0 }, @@ -1819,7 +1352,7 @@ "outputs": [ { "data": { - "image/png": "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ArxcXQYREbkQ/0wlIiIi2WJQISIiItlyaVD55ZdfMHLkSERERECSJGzYsMGV5RAREZHMuDSolJaWonv37li0aJEryyAiIiKZculg2uHDh2P48OGNbq/T6aDT6UzPi4qKHFEWERERyYRbjVGZP38+/P39TY/o6GhXl0REREQO5FZB5cUXX0RhYaHpcf78eVeXRERERA7kVvOoqNVqqNVqV5dBRERETuJWPSpERETUsjCoEBERkWy59NRPSUkJTp8+bXqemZmJ1NRUtGrVCm3atHFhZURERCQHLg0qBw8exMCBA03PZ8yYAQCYMmUKli9f7qKqiIiISC5cGlQGDBgAN755MxERETkYx6gQERGRbDGoEBERkWwxqBAREZFsMagQERGRbDGoEBERkWwxqBAREZFsMagQERGRbDGoEBERkWwxqLgZg1FAbzC6ugwiIiKncOnMtNR4eoMRr317HKsOnIdRCIzoFo5370+AVsUfIRERNV/sUXETC7emY8W+czAYBYQAfjiajbnfHnd1WURERA7FoOImfjxxBbXvimQUwJaTOS6rh4iIyBkYVNyEt9oD0nXLtCqlS2ohIiJyFgYVNzF1YCwAQCEB0h+J5ak74lxYERERkeNxJKabuKNzKL58+BasOlA9TmV09wgM7xbu6rKIiIgcikHFjdzaIQi3dghydRlEREROw1M/REREJFsMKkRERCRbDCpEREQkWwwqdlChNyD9SjFyiitcXQoREVGzwsG0TZR6vgD/t/wA8ksrAQB/v60dXhrRBZJ0/awnREREZC32qDRBZZURD39xAAVllaZly37NxLdHLrmwKiIiouaDQaUJLhaUI6+kEsZac9t7KCQczrrmuqKIiIiaEZ76uU5OUQVmfnUEh7KuoZW3Cq/cFY9hN4VZbNtKq4IEXHcPHoFW3mqn1EpERNTcsUelFoNRYEryfuzOyENZpQEXr5XjyRWHcPic5R4Sf60nnh7cAUB1T4pCAsL9vfBgUowzyyYiImq22KNSy7n8MpzMLjY9FwCUkoTNxy6jZ5tAi6+ZPrgjuoT74UBmPlr5qDChTxsEaFVOqpiIiKh5Y1CpxVNZ90odAcDDwvLahnYNw9Culk8PERERke146qeWyAAv9O8YDMUfuUQhVYeXe3tGubYwIiKiFoo9KrVIkoRPJvXCez+mYX9mPoJ91ZgxpCNig31c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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGwCAYAAACHJU4LAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABJG0lEQVR4nO3dd1gU594+8Ht2YReWrhRpYsGGiqLGHNTYjSVHTbUbkzc5aZoTo6YaozFFk3hOmiW+mmBOXktObMnPJJrE3ivYJYiIBRQE6bDA7vP7g7BhZUF22TIL9+e69kp25tnZ7wy4e/PMM89IQggBIiIiIhlSOLoAIiIiopowqBAREZFsMagQERGRbDGoEBERkWwxqBAREZFsMagQERGRbDGoEBERkWy5OLqA+tDr9UhLS4OXlxckSXJ0OURERFQHQgjk5+cjJCQECkXtfSZOHVTS0tIQHh7u6DKIiIjIAlevXkVYWFitbZw6qHh5eQGo2FFvb28HV0NERER1kZeXh/DwcMP3eG2cOqhUnu7x9vZmUCEiInIydRm2wcG0REREJFsMKkRERCRbDCpEREQkWwwqREREJFsMKkRERCRbDCpEREQkWwwqREREJFsMKkRERCRbDCpEREQkWwwqREREJFsMKkRERCRbTn2vHyIiIrK+58+kYFNmruF5mNoVx3p1dEgt7FEhIiIig31ZeUYhBQCuacvw+MmLDqmHQYWIiIgMXk26ZnL59uwCO1dSgUGFiIiIDNwUksnlppfaHoMKERERGfwnupXJ5S+EBdi5kgoODSrz5s2DJElGj/bt2zuyJCIiokYtzE2Nz9qGGi0b3tQLb7YJreEVtuXwq346duyI33//3fDcxcXhJRERETVqY0MDMDbUMT0od3J4KnBxcUGzZs0cXQYRERHJkMPHqCQlJSEkJAStWrXCxIkTceXKlRrbarVa5OXlGT2IiIio4XJoULn33nuxatUqbN26FcuWLUNKSgruu+8+5Ofnm2y/YMEC+Pj4GB7h4eF2rpiIiIjsSRJCCEcXUSknJwcRERH497//jaeeeqraeq1WC61Wa3iel5eH8PBw5Obmwtvb256lEhERkYXy8vLg4+NTp+9vh49RqcrX1xdt27bFxYumZ79Tq9VQq9V2roqIiIgcxeFjVKoqKChAcnIygoODHV0KERERyYBDg8qsWbOwe/duXL58GQcOHMBDDz0EpVKJ8ePHO7IsIiIikgmHnvq5du0axo8fj6ysLAQEBKBPnz44dOgQAgLkce02EREROZZDg8q6desc+fZEREQkc7Iao0JERERUFYMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREcmWi6MLICIiovop0enxc2YuDuUWIFjlitFBfmilUQMATuQV4lxBCYLVrhjQxAvp2jLsvZ0PtUKBQU294e2iBABkl5VjR1Ye9AD6+3khUO3qwD36C4MKERGREyso12HkiSScLywxLFt0+QbiOrdEUpEW7yanGZbH+njgZH4xivR6AECo2hVburdBiU5g5Ikk3CorBwB4uyixOSYSUZ7u9t0ZExhUiIiInNiyqxm4UCWkAIAOwAtnL6NQL4yWH8wthFTl+Q1tGT5ITsft8nLcLi83LC8s1+HVxKvY0r2tDSuvGwYVIiIiJ5ZaXGpyecEdIaVS1aU6AMnFWtwuK4dOGC9PKdZarcb64GBaIiIiJ9ZG42Zyua9SYfJLvuoyJYAOHm5o7+EOZZWuFqUEtPMwvV17Y1AhIiJyYs+GB6Cnj4fRMrUk4avOLfFhuzCjUz3D/b3h8+fgWQBopVHjzVYheK9NKELUKsNyf1cXLGrX3Nal14kkhDDdN+QE8vLy4OPjg9zcXHh7ezu6HCIiIoco1wvsv12Ao7kFCHZzxaCmPmj251U7F4tKcL6gBKFqV8R4a3C7XIcjOYVQKST08vWEm7Kiz6KwXIcDOQUQAP7m62m4GsgWzPn+ZlAhIiIiuzLn+5unfoiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSI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", "text/plain": [ "
" ] @@ -1844,7 +1377,7 @@ "plt.ylabel(\"-log10(p-value)\")\n", "plt.axhline(-np.log10(0.05), color=\"black\", linestyle=\"--\")\n", "plt.text(\n", - " 0.5,\n", + " 0.65,\n", " 1.5,\n", " f\"Phenotypically active = {100 * active_ratio:.2f}%\",\n", " va=\"center\",\n", @@ -2514,7 +2047,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "3548e3d76a50442f8bd81ca1134e3718", + "model_id": "ec8e2c91620549308119846587c003bf", "version_major": 2, "version_minor": 0 }, @@ -2528,7 +2061,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5f77a556df084428a019a8ba2480599c", + "model_id": "198893cbe0024e6db5e04034ebf9a3ff", "version_major": 2, "version_minor": 0 }, @@ -2735,7 +2268,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f30cc784702349679561e80c0c71a669", + "model_id": "be9fd249e0b544569e330c1e28bd7ed4", "version_major": 2, "version_minor": 0 }, @@ -2749,7 +2282,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c99f02640b394aaf8bf31b346fa610b0", + "model_id": "227b5b7494154b6399b9bded7d1619c8", "version_major": 2, "version_minor": 0 }, diff --git a/src/copairs/matching.py b/src/copairs/matching.py index f840b1c..26651c8 100644 --- a/src/copairs/matching.py +++ b/src/copairs/matching.py @@ -18,6 +18,23 @@ ColumnDict = Dict[str, ColumnList] +def assign_reference_index( + df: pd.DataFrame, + condition: Union[str, pd.Index], + reference_col: str = "Metadata_Reference_Index", + default_value: int = -1, + inplace: bool = False, +): + """Assigns reference index to a specified column based on a given condition.""" + if not inplace: + df = df.copy() + df[reference_col] = default_value + if isinstance(condition, str): + condition = df.query(condition).index + df.loc[condition, reference_col] = condition + return df if not inplace else None + + def reverse_index(col: pd.Series) -> pd.Series: """Build a reverse_index for a given column in the DataFrame""" return pd.Series(col.groupby(col, observed=True).indices, name=col.name) From d2030fa71b957aacae678995f8cbce2107885772 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Mon, 3 Feb 2025 23:22:03 -0500 Subject: [PATCH 15/21] refactor(examples): add null size example; split activity & consistency --- .gitignore | 2 + README.md | 5 +- examples/F1.large.jpg | Bin 178450 -> 0 bytes examples/README.md | 32 + examples/finding_pairs.ipynb | 6 +- examples/null_size.ipynb | 599 ++++++++ ...P_demo.ipynb => phenotypic_activity.ipynb} | 1271 +---------------- examples/phenotypic_consistency.ipynb | 1251 ++++++++++++++++ 8 files changed, 1957 insertions(+), 1209 deletions(-) delete mode 100644 examples/F1.large.jpg create mode 100644 examples/README.md create mode 100644 examples/null_size.ipynb rename examples/{mAP_demo.ipynb => phenotypic_activity.ipynb} (85%) create mode 100644 examples/phenotypic_consistency.ipynb diff --git a/.gitignore b/.gitignore index 68bc17f..cd7f941 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,5 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +examples/data/ \ No newline at end of file diff --git a/README.md b/README.md index dc8d731..39fb3d5 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,9 @@ pytest We provide examples demonstrating how to use copairs for: - [grouping profiles based on their metadata](./examples/finding_pairs.ipynb) -- [calculating mAP to assess phenotypic activity and consistnecy of perturbation using real data](./examples/mAP_demo.ipynb) - +- [calculating mAP to assess phenotypic activity of perturbations](./examples/phenotypic_activity.ipynb) +- [calculating mAP to assess phenotypic consistency of perturbations](./examples/phenotypic_consistency.ipynb) +- [estimating null size for mAP p-value calculation](./examples/null_size.ipynb) ## Citation If you find this work useful for your research, please cite our [pre-print](https://doi.org/10.1101/2024.04.01.587631): diff --git a/examples/F1.large.jpg b/examples/F1.large.jpg deleted file mode 100644 index 82c2023ae39d50dd9ffc24f0f7d205519f9956b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178450 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À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 Wt;5;@AapSLKkPvNOK9@f!v6wXvtcm+ diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..09a6919 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,32 @@ + # Examples + +Example notebooks demostrating the use of `copairs`. + +## Installation + +To install dependencies for running examples, run: +```bash +pip install copairs[demo] +``` + +## Running examples + +```bash +cd examples +notebook +``` + +## List of examples + +We show how to use copairs for: + +- [grouping profiles based on their metadata](./finding_pairs.ipynb) +- [calculating mAP to assess phenotypic activity of perturbations](./phenotypic_activity.ipynb) +- [calculating mAP to assess phenotypic consistency of perturbations](./phenotypic_consistency.ipynb) +- [estimating null size for mAP p-value calculation](./null_size.ipynb) + +## Data used + +In these examples, we used a single plate of profiles from the dataset "cpg0004" (aka LINCS), which contains Cell Painting images of 1,327 small-molecule perturbations of A549 human cells. The wells on each plate were perturbed with 56 different compounds in six different doses. + +> Way, G. P. et al. Morphology and gene expression profiling provide complementary information for mapping cell state. Cell Syst 13, 911–923.e9 (2022). diff --git a/examples/finding_pairs.ipynb b/examples/finding_pairs.ipynb index d8fa818..b04886f 100644 --- a/examples/finding_pairs.ipynb +++ b/examples/finding_pairs.ipynb @@ -107,7 +107,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -278,7 +278,7 @@ ], "metadata": { "kernelspec": { - "display_name": "map_benchmark", + "display_name": "copairs", "language": "python", "name": "python3" }, @@ -292,7 +292,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.9.19" } }, "nbformat": 4, diff --git a/examples/null_size.ipynb b/examples/null_size.ipynb new file mode 100644 index 0000000..87cc60c --- /dev/null +++ b/examples/null_size.ipynb @@ -0,0 +1,599 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Determining null size for mAP p-value calculation" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy.special import comb\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from copairs import map" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_scatter_grid(\n", + " data,\n", + " null_size_col=\"null_size\",\n", + " x_col=\"mAP\",\n", + " y_col=\"-log10(p-value)\",\n", + " color_col=\"below_corrected_p\",\n", + " cmap=\"tab10\",\n", + " figsize=(12, 6),\n", + "):\n", + " \"\"\"Plots a grid of scatter plots for different values of a given column.\n", + "\n", + " Args:\n", + " data (pd.DataFrame): Input DataFrame containing the data.\n", + " null_size_col (str): Column to split data into subplots. Defaults to \"null_size\".\n", + " x_col (str): Column to use for the x-axis. Defaults to \"mean_average_precision\".\n", + " y_col (str): Column to use for the y-axis. Defaults to \"-log10(p-value)\".\n", + " color_col (str): Column for coloring points. Defaults to \"below_corrected_p\".\n", + " cmap (str): Colormap for the scatter plot. Defaults to \"tab10\".\n", + " figsize (tuple): Figure size. Defaults to (12, 6).\n", + " \"\"\"\n", + " unique_null_sizes = sorted(data[null_size_col].unique()) # Get unique values\n", + " n_rows, n_cols = 3, 4 # Define grid shape\n", + "\n", + " fig, axes = plt.subplots(n_rows, n_cols, figsize=figsize, sharex=True, sharey=True)\n", + " axes = axes.flatten() # Flatten for easy iteration\n", + "\n", + " for i, null_size in enumerate(unique_null_sizes):\n", + " ax = axes[i]\n", + " subset = data[data[null_size_col] == null_size] # Filter data for current panel\n", + "\n", + " # Compute active ratio for the subset\n", + " active_ratio = subset[color_col].mean()\n", + "\n", + " # Scatter plot\n", + " _ = ax.scatter(\n", + " subset[x_col], subset[y_col], c=subset[color_col], cmap=cmap, s=10\n", + " )\n", + "\n", + " ax.axhline(\n", + " -np.log10(0.05), color=\"black\", linestyle=\"--\"\n", + " ) # Significance threshold\n", + " ax.set_title(f\"{null_size_col} = {null_size}\")\n", + "\n", + " # Display active ratio per panel\n", + " ax.text(\n", + " 0.4,\n", + " 5,\n", + " f\"Active = {100 * active_ratio:.2f}%\",\n", + " va=\"center\",\n", + " ha=\"left\",\n", + " fontsize=9,\n", + " )\n", + "\n", + " if i % n_cols == 0: # Leftmost column\n", + " ax.set_ylabel(y_col)\n", + " if i >= (n_rows - 1) * n_cols: # Bottom row\n", + " ax.set_xlabel(x_col)\n", + "\n", + " fig.suptitle(f\"Scatter plots across different {null_size_col} values\", fontsize=14)\n", + " plt.tight_layout(rect=[0, 0.05, 1, 0.95]) # Adjust layout\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load data\n", + "\n", + "This example relies on data and results from the [Phenotypic activity](./phenotypic_activity.ipynb) example, so run that one first if you haven't.\n", + "\n", + "Let's define some helper functions." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "df_activity = pd.read_csv(\"data/2016_04_01_a549_48hr_batch1_plateSQ00014812.csv\")\n", + "activity_ap = pd.read_csv(\"data/activity_ap.csv\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Complete null size\n", + "\n", + "We estimate the statistical significance of a mAP score with respect to a random baseline using a permutation testing approach, a non-parametric, assumption-free method for testing the null hypothesis of sample exchangeability. The complete AP null distribution consists of all possible rank list re-shuffles.\n", + "\n", + "Let $m$ to be the number of perturbation replicates and $n$ to be the number of control profiles. Given that one perturbation profile serves as a query, the complete null size $d$ can be calculated as a binomial coefficient:\n", + "\n", + "\\begin{equation}\n", + " d_{null} = \\binom{(m-1)}{(m-1)*n}\n", + "\\end{equation}\n", + "\n", + "Let's calculate the complete null size for the example dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "m=6, n=24, d=118755\n" + ] + } + ], + "source": [ + "# almost all perturbations have 6 replicates\n", + "m = (\n", + " df_activity.query(\"Metadata_broad_sample != 'DMSO'\")\n", + " .groupby(\"Metadata_broad_sample\")\n", + " .size()\n", + " .mode()[0]\n", + ")\n", + "# the number of control profiles is 24\n", + "n = df_activity.query(\"Metadata_broad_sample == 'DMSO'\").shape[0]\n", + "\n", + "# using SciPy's comb function for numerical stability\n", + "d = comb(m - 1 + n, m - 1, exact=True)\n", + "\n", + "print(f\"{m=}, {n=}, {d=}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For large datasets, computing the full combinatorial null is infeasible. Instead, we approximate the null distribution using Monte Carlo sampling with $d_{\\text{perm}}$ permutations:\n", + "\n", + "\\begin{equation}\n", + " null\\_size \\approx d_{null}\n", + "\\end{equation}\n", + "\n", + "where $null\\_size$ is the number of random rank list shufflings applied to estimate the null distribution.\n", + "\n", + "## Effect of null size on mAP p-value calculation\n", + "\n", + "Let's calculate mAP significance on the given dataset using `null_size` values from $10$ to $5*10^6$ and plot results below." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f757e36886c54b19af4b8c7c1fe77e55", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/2 [00:00" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "activity_maps = []\n", + "for ns_pow in range(1, 7):\n", + " null_size = 10**ns_pow\n", + "\n", + " replicate_map = map.mean_average_precision(\n", + " activity_ap,\n", + " [\"Metadata_broad_sample\"],\n", + " null_size=null_size,\n", + " threshold=0.05,\n", + " seed=0,\n", + " )\n", + " replicate_map[\"null_size\"] = null_size\n", + " activity_maps.append(replicate_map)\n", + "\n", + " replicate_map = map.mean_average_precision(\n", + " activity_ap,\n", + " [\"Metadata_broad_sample\"],\n", + " null_size=5 * null_size,\n", + " threshold=0.05,\n", + " seed=0,\n", + " )\n", + " replicate_map[\"null_size\"] = 5 * null_size\n", + " activity_maps.append(replicate_map)\n", + "\n", + "activity_maps = pd.concat(activity_maps)\n", + "activity_maps.rename(columns={\"mean_average_precision\": \"mAP\"}, inplace=True)\n", + "activity_maps[\"-log10(p-value)\"] = -activity_maps[\"corrected_p_value\"].apply(np.log10)\n", + "\n", + "plot_scatter_grid(activity_maps)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because the full null size $d_{null}=118755$, smaller sample sizes ($<5,000$) lead to poor estimation of significance for these data, while very large values ($>100,000$) cover the whole null and do not affect perturbation ranking results.\n", + "\n", + "## Practical consideration for choosing null size\n", + "\n", + "In practice, drawing a large number of samples is not always feasible, because compute time for each AP calculation grows with the higher number of perturbations of the dataset, the number of metadata constraints for profile grouping, sizes of perturbation groups (the number of perturbation replicates) and control groups (the number of control replicates), and profile dimensionality (the number of features in a profile).\n", + "\n", + "Finding a `null_size` that works for a particular dataset is balancing between test resolution (for example, being able to tell apart vary small p-values) and compute. We provided `null_size` values for each real-world dataset in Supplemental Materials to our paper—please refer to:\n", + "\n", + "> Kalinin, A. A. et al. A versatile information retrieval framework for evaluating profile strength and similarity. bioRxiv, 2024-04, (2024)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "copairs", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/mAP_demo.ipynb b/examples/phenotypic_activity.ipynb similarity index 85% rename from examples/mAP_demo.ipynb rename to examples/phenotypic_activity.ipynb index 808116b..32f8be8 100644 --- a/examples/mAP_demo.ipynb +++ b/examples/phenotypic_activity.ipynb @@ -1,8 +1,15 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# mAP for phenotypic activity assesement" + ] + }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -20,9 +27,13 @@ "source": [ "## Introduction\n", "\n", - "This example demostrates how to use `copairs` to:\n", - "- assess phenotypic activity of perturbations' replicates against DMSO control replicates and\n", - "- assess phenotypic consistncy of perturbations htat target the same gene against other perturbations.\n", + "This example demostrates how to use `copairs` to assess phenotypic activity of perturbations in a profiling dataset.\n", + "\n", + "Phenotypic activity is assessed by calculating mean average precision (mAP) for the retrieval of replicates of a perturbation against replicates of negative controls.\n", + "\n", + "It aims to answer the question: “How distinguishable is this perturbation from negative controls?”\n", + "\n", + "The resulting perturbation mAP score reflects the average extent to which its replicate profiles are more similar to each other compared to control profiles (Figure 1E).\n", "\n", "Citation:\n", "> Kalinin, A. A. et al. A versatile information retrieval framework for evaluating profile strength and similarity. bioRxiv, 2024-04, (2024)." @@ -30,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -45,7 +56,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -61,7 +72,7 @@ } ], "source": [ - "fig1_path = \"F1.large.jpg\"\n", + "fig1_path = \"data/F1.large.jpg\"\n", "fig1_url = \"https://www.biorxiv.org/content/biorxiv/early/2024/04/02/2024.04.01.587631/F1.large.jpg\"\n", "\n", "if not Path(fig1_path).is_file():\n", @@ -85,7 +96,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -549,17 +560,23 @@ "[384 rows x 507 columns]" ] }, - "execution_count": 4, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "local_path = \"data/2016_04_01_a549_48hr_batch1_plateSQ00014812.csv\"\n", "commit = \"da8ae6a3bc103346095d61b4ee02f08fc85a5d98\"\n", "plate = \"SQ00014812\"\n", "url = f\"https://media.githubusercontent.com/media/broadinstitute/lincs-cell-painting/{commit}/profiles/2016_04_01_a549_48hr_batch1/{plate}/{plate}_normalized_feature_select.csv.gz\"\n", "\n", - "df = pd.read_csv(url)\n", + "if not Path(local_path).is_file():\n", + " df = pd.read_csv(url)\n", + " df.to_csv(local_path, index=False)\n", + "else:\n", + " df = pd.read_csv(local_path)\n", + "\n", "df = df.loc[:, df.nunique() > 1] # remove constant columns\n", "df" ] @@ -573,7 +590,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -600,7 +617,7 @@ " 'BCL2|BCL2L1|BCL2L2'], dtype=object)" ] }, - "execution_count": 5, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -613,9 +630,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Assessing phenotypic activity of compounds with mAP\n", - "\n", - "Phenotypic activity of a perturbation reflects the average extent to which its replicate profiles are more similar to each other compared to control profiles (Figure 1E)." + "## Assessing phenotypic activity of compounds with mAP" ] }, { @@ -624,12 +639,12 @@ "source": [ "Here, we treat different doses of each compound as replicates and assess how well we can retrieve them by similarity against the group of negative controls (DMSO).\n", "\n", - "To ensure correct grouping of profiles, we can add a dummy column that is equal to row index for all DMSO replicates and to -1 for all compound replicates. " + "For phenotypic activity, it's helpful to add an extra column that is equal to row index for all DMSO replicates and to -1 for all compound replicates using `assign_reference_index` function. This helps to not count groups of negative controls as query groups and not consider other perturbations as a reference." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -637,7 +652,7 @@ "\n", "df_activity = assign_reference_index(\n", " df,\n", - " \"Metadata_broad_sample == 'DMSO'\", # condition to get reference profiles (neg controls for activity)\n", + " \"Metadata_broad_sample == 'DMSO'\", # condition to get reference profiles (neg controls)\n", " reference_col=reference_col,\n", " default_value=-1,\n", ")" @@ -655,12 +670,17 @@ "\n", "* Two profiles are a negative pair when one of them belongs to a group of compound replicates and another to a group of DMSO controls. That means they should be different both in the metadata column that identifies the specific compound and the reference index columns that we created. The latter is needed to ensure that replicates of compounds are retrieved against only DMSO controls at this stage (and not against replicates of other compounds). We list these columns in `neg_diffby`.\n", "\n", - "* Profiles that form a negative pair do not need to be same in any of the metatada columns, so we keep `neg_sameby` empty." + "* Profiles that form a negative pair do not need to be same in any of the metatada columns, so we keep `neg_sameby` empty.\n", + "\n", + "\n", + "Finally, we include `Metadata_reference_index` column to:\n", + "* `pos_sameby`—this ensures positive pairs connect profiles that share the same value in this column, i.e. a positive pair cannot be formed between any two negative controls (control profiles contain index values).\n", + "* `neg_diffby`—this ensures negative pairs connect profiles that differ in this columns, i.e. a negative pair cannot be formed between profiles of two different perturbations (all perturbation profiles contain -1)." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -684,13 +704,13 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "51e0cabc26764909bf69fefe2213491b", + "model_id": "3cfeabe4061942f499ad5045f1262f51", "version_major": 2, "version_minor": 0 }, @@ -704,7 +724,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c498f5cd080e4b1193c1dcb7a25b2b2b", + "model_id": "2c3953577f684964825b1d337b3a06bd", "version_major": 2, "version_minor": 0 }, @@ -1083,7 +1103,7 @@ "[360 rows x 18 columns]" ] }, - "execution_count": 8, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1092,11 +1112,12 @@ "metadata = df_activity.filter(regex=\"^Metadata\")\n", "profiles = df_activity.filter(regex=\"^(?!Metadata)\").values\n", "\n", - "replicate_aps = map.average_precision(\n", + "activity_ap = map.average_precision(\n", " metadata, profiles, pos_sameby, pos_diffby, neg_sameby, neg_diffby\n", ")\n", - "replicate_aps = replicate_aps.query(\"Metadata_broad_sample != 'DMSO'\") # remove DMSO\n", - "replicate_aps" + "activity_ap = activity_ap.query(\"Metadata_broad_sample != 'DMSO'\") # remove DMSO\n", + "activity_ap.to_csv(\"data/activity_ap.csv\", index=False)\n", + "activity_ap" ] }, { @@ -1105,18 +1126,20 @@ "source": [ "At the next step, we average replicate AP scores at the per-compound level to obtain mAP values using `mean_average_precision`.\n", "\n", - "It also calculates p-values using permutation testing, and performs FDR correction to compare across compounds." + "It also calculates p-values using permutation testing, and performs FDR correction to compare across compounds.\n", + "\n", + "For more information on choosing `null size` parameter see the [Null size](./null_size.ipynb) example." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "893c58d190a84aa5953e1211feb581b7", + "model_id": "3c684ee9c2094831a91b21b14dcbb2b0", "version_major": 2, "version_minor": 0 }, @@ -1130,7 +1153,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "67fdff1eb18e45bdb45a314a10ed9c18", + "model_id": "45ecff1fd6544ec78fc8b7ec5203e842", "version_major": 2, "version_minor": 0 }, @@ -1325,17 +1348,17 @@ "9 0.588166 " ] }, - "execution_count": 9, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "replicate_maps = map.mean_average_precision(\n", - " replicate_aps, pos_sameby, null_size=1000000, threshold=0.05, seed=0\n", + "activity_map = map.mean_average_precision(\n", + " activity_ap, pos_sameby, null_size=1000000, threshold=0.05, seed=0\n", ")\n", - "replicate_maps[\"-log10(p-value)\"] = -replicate_maps[\"corrected_p_value\"].apply(np.log10)\n", - "replicate_maps.head(10)" + "activity_map[\"-log10(p-value)\"] = -activity_map[\"corrected_p_value\"].apply(np.log10)\n", + "activity_map.head(10)" ] }, { @@ -1347,12 +1370,12 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 25, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGwCAYAAACHJU4LAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABJG0lEQVR4nO3dd1gU594+8Ht2YReWrhRpYsGGiqLGHNTYjSVHTbUbkzc5aZoTo6YaozFFk3hOmiW+mmBOXktObMnPJJrE3ivYJYiIBRQE6bDA7vP7g7BhZUF22TIL9+e69kp25tnZ7wy4e/PMM89IQggBIiIiIhlSOLoAIiIiopowqBAREZFsMagQERGRbDGoEBERkWwxqBAREZFsMagQERGRbDGoEBERkWy5OLqA+tDr9UhLS4OXlxckSXJ0OURERFQHQgjk5+cjJCQECkXtfSZOHVTS0tIQHh7u6DKIiIjIAlevXkVYWFitbZw6qHh5eQGo2FFvb28HV0NERER1kZeXh/DwcMP3eG2cOqhUnu7x9vZmUCEiInIydRm2wcG0REREJFsMKkRERCRbDCpEREQkWwwqREREJFsMKkRERCRbDCpEREQkWwwqREREJFsMKkRERCRbDCpEREQkWwwqREREJFsMKkRERCRbTn2vHyIiIrK+58+kYFNmruF5mNoVx3p1dEgt7FEhIiIig31ZeUYhBQCuacvw+MmLDqmHQYWIiIgMXk26ZnL59uwCO1dSgUGFiIiIDNwUksnlppfaHoMKERERGfwnupXJ5S+EBdi5kgoODSrz5s2DJElGj/bt2zuyJCIiokYtzE2Nz9qGGi0b3tQLb7YJreEVtuXwq346duyI33//3fDcxcXhJRERETVqY0MDMDbUMT0od3J4KnBxcUGzZs0cXQYRERHJkMPHqCQlJSEkJAStWrXCxIkTceXKlRrbarVa5OXlGT2IiIio4XJoULn33nuxatUqbN26FcuWLUNKSgruu+8+5Ofnm2y/YMEC+Pj4GB7h4eF2rpiIiIjsSRJCCEcXUSknJwcRERH497//jaeeeqraeq1WC61Wa3iel5eH8PBw5Obmwtvb256lEhERkYXy8vLg4+NTp+9vh49RqcrX1xdt27bFxYumZ79Tq9VQq9V2roqIiIgcxeFjVKoqKChAcnIygoODHV0KERERyYBDg8qsWbOwe/duXL58GQcOHMBDDz0EpVKJ8ePHO7IsIiIikgmHnvq5du0axo8fj6ysLAQEBKBPnz44dOgQAgLkce02EREROZZDg8q6desc+fZEREQkc7Iao0JERERUFYMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREckWgwoRERHJFoMKERERyRaDChEREcmWi6MLICIiovop0enxc2YuDuUWIFjlitFBfmilUQMATuQV4lxBCYLVrhjQxAvp2jLsvZ0PtUKBQU294e2iBABkl5VjR1Ye9AD6+3khUO3qwD36C4MKERGREyso12HkiSScLywxLFt0+QbiOrdEUpEW7yanGZbH+njgZH4xivR6AECo2hVburdBiU5g5Ikk3CorBwB4uyixOSYSUZ7u9t0ZExhUiIiInNiyqxm4UCWkAIAOwAtnL6NQL4yWH8wthFTl+Q1tGT5ITsft8nLcLi83LC8s1+HVxKvY0r2tDSuvGwYVIiIiJ5ZaXGpyecEdIaVS1aU6AMnFWtwuK4dOGC9PKdZarcb64GBaIiIiJ9ZG42Zyua9SYfJLvuoyJYAOHm5o7+EOZZWuFqUEtPMwvV17Y1AhIiJyYs+GB6Cnj4fRMrUk4avOLfFhuzCjUz3D/b3h8+fgWQBopVHjzVYheK9NKELUKsNyf1cXLGrX3Nal14kkhDDdN+QE8vLy4OPjg9zcXHh7ezu6HCIiIoco1wvsv12Ao7kFCHZzxaCmPmj251U7F4tKcL6gBKFqV8R4a3C7XIcjOYVQKST08vWEm7Kiz6KwXIcDOQUQAP7m62m4GsgWzPn+ZlAhIiIiuzLn+5unfoiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSIiIhIthhUiIiISLYYVIiIiEi2GFSI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", + "image/png": "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ICAAwO0vV+D2sXzg9hyXoKAgs8e6deuQkJBg9n6tVougoKBCy8xfHgCcP38eoaGh8PHxMetXp04d0+t3U7t2bTRt2hQLFiwwtS1YsAAPPvggoqOjzfqqVCpUq1bNrK1mzZoAgHPnzllcfmJiIlJTU1GvXr271mLJypUr8eCDD0Kr1aJChQoICgrC7NmzzeZAxMfHQ6VSISYmxqp1WNKvXz9kZWXhl19+AQCkp6dj1apV6NOnj1XhJ3+ZGo3GtK9TUlKwcuVKDBo06K7LTEpKwquvvorKlSvD09MTQUFBqFq1qmk5+T766CMcOXIEERERaNasGSZMmGD2xVu1alWMGjUKc+fORWBgILp06YKZM2eaLePUqVMQEdSoUaPQz+rx48dNP6u2XFa+8PDwQvvCz88PERERhdqAf/59JSYmIjk5Gf/9738Lrefpp58GgELrutu/WaKCeNYPuaxmzZpZHAm4k1qtttguf080NRqNAID58+cjODi4UL87T+ctann2MGTIELz66qu4dOkS9Ho9du7ciRkzZjhs/UX5/fff8cgjj6BNmzaYNWsWQkJC4O7ujri4OCxcuNCu637wwQcRFRWFH374AQMHDsT//vc/ZGVloV+/flYvMyAgAP/617+wYMECvPvuu/jpp5+g1+stjlzdqW/fvti+fTvGjBmDRo0awdvbG0ajEV27djX9bOX3a926NZYvX45169bh448/xocffohly5ahW7duAIBPPvkETz31FH7++WesW7cO//73vzF16lTs3LkT4eHhMBqNUBQFq1evtvhz6O3tbfp/Wy4LKPrnvqT/vp588kkMHTrUYt8GDRqUaplEBTGo0D2vevXqAIBKlSqhU6dONllmZGQk1q9fj7S0NLNRlRMnTphez1fcX+z9+/fHqFGjsGjRImRlZcHd3d3iF7LRaMSZM2dMoygA8NdffwFAkWdDBAUFwdfXF0eOHCnVtgHA0qVLodVqsXbtWmg0GlN7XFycWb/q1avDaDTi2LFjxV67pLQjIX379sUXX3yB1NRULFmyBFFRUabDLdauY8iQIejVqxf27NmDBQsWIDY2FnXr1i32Pbdu3cKGDRswceJEvPvuu6b2/FG6O4WEhODll1/Gyy+/jISEBDzwwAN4//33TUEFAOrXr4/69evjnXfewfbt29GqVSt89dVXmDx5MqpXrw4RQdWq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", "text/plain": [ "

" ] @@ -1362,17 +1385,17 @@ } ], "source": [ - "active_ratio = replicate_maps.below_corrected_p.mean()\n", + "active_ratio = activity_map.below_corrected_p.mean()\n", "\n", "plt.scatter(\n", - " data=replicate_maps,\n", + " data=activity_map,\n", " x=\"mean_average_precision\",\n", " y=\"-log10(p-value)\",\n", " c=\"below_corrected_p\",\n", " cmap=\"tab10\",\n", " s=10,\n", ")\n", - "# 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r',\n", + "plt.title(\"Phenotypic activity assesement\")\n", "plt.xlabel(\"mAP\")\n", "plt.ylabel(\"-log10(p-value)\")\n", "plt.axhline(-np.log10(0.05), color=\"black\", linestyle=\"--\")\n", @@ -1386,1174 +1409,14 @@ "plt.show()" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Assessing phenotypic consistency of compounds grouped by targets\n", - "\n", - "Phenotypic consitency of a group of perturbations reflects the average extent to which members of this group are more similar to each other compared to other groups (see Figure 1F).\n", - "\n", - "First, we are going to filter out compounds that were not phenotypically active using mAP p-values from the previous section.\n", - "\n", - "Next, we will aggregate each compound’s replicate profiles into a \"consensus\" profile by taking the median of each feature to reduce profile noise and improve computational efficiency." - ] - }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 26, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Metadata_broad_sampleMetadata_mg_per_mlMetadata_mmoles_per_literMetadata_pert_idMetadata_pert_mfc_idMetadata_pert_wellMetadata_broad_sample_typeMetadata_pert_typeMetadata_broad_idMetadata_InChIKey14...Nuclei_Texture_InverseDifferenceMoment_AGP_5_0Nuclei_Texture_InverseDifferenceMoment_DNA_20_0Nuclei_Texture_InverseDifferenceMoment_ER_5_0Nuclei_Texture_InverseDifferenceMoment_Mito_10_0Nuclei_Texture_InverseDifferenceMoment_Mito_5_0Nuclei_Texture_SumAverage_RNA_5_0Nuclei_Texture_SumEntropy_DNA_10_0Nuclei_Texture_SumEntropy_DNA_20_0Nuclei_Texture_SumEntropy_DNA_5_0Nuclei_Texture_Variance_RNA_10_0
6BRD-K74363950-004-01-05.65560010.000000BRD-K74363950BRD-K74363950-004-01-0A07trttrtBRD-K74363950ASMXXROZKSBQIH...-0.51038-0.764021.616400-0.49600-0.4813602.4211001.107901.138201.143200.329230
7BRD-K74363950-004-01-01.8852003.333300BRD-K74363950BRD-K74363950-004-01-0A08trttrtBRD-K74363950ASMXXROZKSBQIH...-0.23602-0.411290.3049600.478840.005852-0.7103300.41986-0.238880.54949-0.092826
8BRD-K74363950-004-01-00.6284001.111100BRD-K74363950BRD-K74363950-004-01-0A09trttrtBRD-K74363950ASMXXROZKSBQIH...-0.52939-0.547270.7225700.733990.2238500.0358420.333180.390640.42969-0.811390
9BRD-K74363950-004-01-00.2094700.370370BRD-K74363950BRD-K74363950-004-01-0A10trttrtBRD-K74363950ASMXXROZKSBQIH...-0.58515-0.415330.0448740.763740.062913-0.6568500.18149-0.109600.48699-0.345260
10BRD-K74363950-004-01-00.0698230.123460BRD-K74363950BRD-K74363950-004-01-0A11trttrtBRD-K74363950ASMXXROZKSBQIH...-0.52686-0.578230.5916100.851840.5603700.0391840.598640.441230.75783-0.018031
11BRD-K74363950-004-01-00.0232740.041152BRD-K74363950BRD-K74363950-004-01-0A12trttrtBRD-K74363950ASMXXROZKSBQIH...-0.48060-1.472200.8141500.794630.0892490.0722400.918280.396261.09120-0.243750
12BRD-K75958547-238-01-04.61540010.000000BRD-K75958547BRD-K75958547-238-01-0A13trttrtBRD-K75958547VGYFMXBACGZSIL...-5.89680-0.97404-5.025000-10.41400-6.0675007.6257003.318303.27410-2.122402.299300
\n", - "

7 rows × 507 columns

\n", - "
" - ], - "text/plain": [ - " Metadata_broad_sample Metadata_mg_per_ml Metadata_mmoles_per_liter \\\n", - "6 BRD-K74363950-004-01-0 5.655600 10.000000 \n", - "7 BRD-K74363950-004-01-0 1.885200 3.333300 \n", - "8 BRD-K74363950-004-01-0 0.628400 1.111100 \n", - "9 BRD-K74363950-004-01-0 0.209470 0.370370 \n", - "10 BRD-K74363950-004-01-0 0.069823 0.123460 \n", - "11 BRD-K74363950-004-01-0 0.023274 0.041152 \n", - "12 BRD-K75958547-238-01-0 4.615400 10.000000 \n", - "\n", - " Metadata_pert_id Metadata_pert_mfc_id Metadata_pert_well \\\n", - "6 BRD-K74363950 BRD-K74363950-004-01-0 A07 \n", - "7 BRD-K74363950 BRD-K74363950-004-01-0 A08 \n", - "8 BRD-K74363950 BRD-K74363950-004-01-0 A09 \n", - "9 BRD-K74363950 BRD-K74363950-004-01-0 A10 \n", - "10 BRD-K74363950 BRD-K74363950-004-01-0 A11 \n", - "11 BRD-K74363950 BRD-K74363950-004-01-0 A12 \n", - "12 BRD-K75958547 BRD-K75958547-238-01-0 A13 \n", - "\n", - " Metadata_broad_sample_type Metadata_pert_type Metadata_broad_id \\\n", - "6 trt trt BRD-K74363950 \n", - "7 trt trt BRD-K74363950 \n", - "8 trt trt BRD-K74363950 \n", - "9 trt trt BRD-K74363950 \n", - "10 trt trt BRD-K74363950 \n", - "11 trt trt BRD-K74363950 \n", - "12 trt trt BRD-K75958547 \n", - "\n", - " Metadata_InChIKey14 ... Nuclei_Texture_InverseDifferenceMoment_AGP_5_0 \\\n", - "6 ASMXXROZKSBQIH ... -0.51038 \n", - "7 ASMXXROZKSBQIH ... -0.23602 \n", - "8 ASMXXROZKSBQIH ... -0.52939 \n", - "9 ASMXXROZKSBQIH ... -0.58515 \n", - "10 ASMXXROZKSBQIH ... -0.52686 \n", - "11 ASMXXROZKSBQIH ... -0.48060 \n", - "12 VGYFMXBACGZSIL ... -5.89680 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_DNA_20_0 \\\n", - "6 -0.76402 \n", - "7 -0.41129 \n", - "8 -0.54727 \n", - "9 -0.41533 \n", - "10 -0.57823 \n", - "11 -1.47220 \n", - "12 -0.97404 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_ER_5_0 \\\n", - "6 1.616400 \n", - "7 0.304960 \n", - "8 0.722570 \n", - "9 0.044874 \n", - "10 0.591610 \n", - "11 0.814150 \n", - "12 -5.025000 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_Mito_10_0 \\\n", - "6 -0.49600 \n", - "7 0.47884 \n", - "8 0.73399 \n", - "9 0.76374 \n", - "10 0.85184 \n", - "11 0.79463 \n", - "12 -10.41400 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_Mito_5_0 \\\n", - "6 -0.481360 \n", - "7 0.005852 \n", - "8 0.223850 \n", - "9 0.062913 \n", - "10 0.560370 \n", - "11 0.089249 \n", - "12 -6.067500 \n", - "\n", - " Nuclei_Texture_SumAverage_RNA_5_0 Nuclei_Texture_SumEntropy_DNA_10_0 \\\n", - "6 2.421100 1.10790 \n", - "7 -0.710330 0.41986 \n", - "8 0.035842 0.33318 \n", - "9 -0.656850 0.18149 \n", - "10 0.039184 0.59864 \n", - "11 0.072240 0.91828 \n", - "12 7.625700 3.31830 \n", - "\n", - " Nuclei_Texture_SumEntropy_DNA_20_0 Nuclei_Texture_SumEntropy_DNA_5_0 \\\n", - "6 1.13820 1.14320 \n", - "7 -0.23888 0.54949 \n", - "8 0.39064 0.42969 \n", - "9 -0.10960 0.48699 \n", - "10 0.44123 0.75783 \n", - "11 0.39626 1.09120 \n", - "12 3.27410 -2.12240 \n", - "\n", - " Nuclei_Texture_Variance_RNA_10_0 \n", - "6 0.329230 \n", - "7 -0.092826 \n", - "8 -0.811390 \n", - "9 -0.345260 \n", - "10 -0.018031 \n", - "11 -0.243750 \n", - "12 2.299300 \n", - "\n", - "[7 rows x 507 columns]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "# only keep active compounds, i.e. those with corrected p-value < 0.05\n", - "active_compounds = replicate_maps.query(\"below_corrected_p\")[\"Metadata_broad_sample\"]\n", - "df_consistent = df.query(\"Metadata_broad_sample in @active_compounds\")\n", - "df_consistent.head(7)" + "activity_map.to_csv(\"data/activity_map.csv\", index=False)" ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Metadata_broad_sampleMetadata_targetCells_AreaShape_EccentricityCells_AreaShape_ExtentCells_AreaShape_FormFactorCells_AreaShape_OrientationCells_AreaShape_SolidityCells_AreaShape_Zernike_0_0Cells_AreaShape_Zernike_1_1Cells_AreaShape_Zernike_2_0...Nuclei_Texture_InverseDifferenceMoment_AGP_5_0Nuclei_Texture_InverseDifferenceMoment_DNA_20_0Nuclei_Texture_InverseDifferenceMoment_ER_5_0Nuclei_Texture_InverseDifferenceMoment_Mito_10_0Nuclei_Texture_InverseDifferenceMoment_Mito_5_0Nuclei_Texture_SumAverage_RNA_5_0Nuclei_Texture_SumEntropy_DNA_10_0Nuclei_Texture_SumEntropy_DNA_20_0Nuclei_Texture_SumEntropy_DNA_5_0Nuclei_Texture_Variance_RNA_10_0
0BRD-A69636825-003-04-7[CACNA1C, CACNA1S, CACNA2D1, CACNG1, HTR3A, KC...-0.3263650.6516100.2112800.0924120.4569150.4865150.4355450.863160...0.1752000.557360-0.8594650.4090450.201909-1.003185-1.405850-1.495100-0.867225-0.066115
1BRD-A69815203-001-07-6[ABCB11, CAMLG, FPR1, PPIA, PPIF, PPP3CA, PPP3...2.487450-2.8727500.616635-0.451942-2.260100-3.3009000.316320-1.825400...-2.681800-0.197230-4.7173500.6441701.3241000.1030700.9860251.3462000.773450-2.749350
2BRD-A70858459-001-01-7[ESR1, ESR2, MAP1A, MAP2]-0.9202101.4615500.445630-0.3942351.5284501.116100-0.0549901.061270...0.2388750.3264750.0645630.1876460.200447-0.6956600.1002250.4018850.114583-0.245753
3BRD-A72309220-001-04-1[HTR1A, HTR1B, HTR1D, HTR1E, HTR1F, HTR2A, HTR...0.0454350.0997550.1036280.592620-0.3522000.202930-0.059855-0.353755...1.069575-0.475915-0.1740020.2179650.090715-0.1546950.165235-0.1601910.242195-0.126886
4BRD-A73368467-003-17-6[HRH1]-0.062074-0.3148200.526190-0.502485-0.444675-0.1912250.1450190.018870...0.527805-1.2042500.615420-0.1876450.3218801.0132350.7936750.6829251.0755000.844115
\n", - "

5 rows × 495 columns

\n", - "
" - ], - "text/plain": [ - " Metadata_broad_sample Metadata_target \\\n", - "0 BRD-A69636825-003-04-7 [CACNA1C, CACNA1S, CACNA2D1, CACNG1, HTR3A, KC... \n", - "1 BRD-A69815203-001-07-6 [ABCB11, CAMLG, FPR1, PPIA, PPIF, PPP3CA, PPP3... \n", - "2 BRD-A70858459-001-01-7 [ESR1, ESR2, MAP1A, MAP2] \n", - "3 BRD-A72309220-001-04-1 [HTR1A, HTR1B, HTR1D, HTR1E, HTR1F, HTR2A, HTR... \n", - "4 BRD-A73368467-003-17-6 [HRH1] \n", - "\n", - " Cells_AreaShape_Eccentricity Cells_AreaShape_Extent \\\n", - "0 -0.326365 0.651610 \n", - "1 2.487450 -2.872750 \n", - "2 -0.920210 1.461550 \n", - "3 0.045435 0.099755 \n", - "4 -0.062074 -0.314820 \n", - "\n", - " Cells_AreaShape_FormFactor Cells_AreaShape_Orientation \\\n", - "0 0.211280 0.092412 \n", - "1 0.616635 -0.451942 \n", - "2 0.445630 -0.394235 \n", - "3 0.103628 0.592620 \n", - "4 0.526190 -0.502485 \n", - "\n", - " Cells_AreaShape_Solidity Cells_AreaShape_Zernike_0_0 \\\n", - "0 0.456915 0.486515 \n", - "1 -2.260100 -3.300900 \n", - "2 1.528450 1.116100 \n", - "3 -0.352200 0.202930 \n", - "4 -0.444675 -0.191225 \n", - "\n", - " Cells_AreaShape_Zernike_1_1 Cells_AreaShape_Zernike_2_0 ... \\\n", - "0 0.435545 0.863160 ... \n", - "1 0.316320 -1.825400 ... \n", - "2 -0.054990 1.061270 ... \n", - "3 -0.059855 -0.353755 ... \n", - "4 0.145019 0.018870 ... \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_AGP_5_0 \\\n", - "0 0.175200 \n", - "1 -2.681800 \n", - "2 0.238875 \n", - "3 1.069575 \n", - "4 0.527805 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_DNA_20_0 \\\n", - "0 0.557360 \n", - "1 -0.197230 \n", - "2 0.326475 \n", - "3 -0.475915 \n", - "4 -1.204250 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_ER_5_0 \\\n", - "0 -0.859465 \n", - "1 -4.717350 \n", - "2 0.064563 \n", - "3 -0.174002 \n", - "4 0.615420 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_Mito_10_0 \\\n", - "0 0.409045 \n", - "1 0.644170 \n", - "2 0.187646 \n", - "3 0.217965 \n", - "4 -0.187645 \n", - "\n", - " Nuclei_Texture_InverseDifferenceMoment_Mito_5_0 \\\n", - "0 0.201909 \n", - "1 1.324100 \n", - "2 0.200447 \n", - "3 0.090715 \n", - "4 0.321880 \n", - "\n", - " Nuclei_Texture_SumAverage_RNA_5_0 Nuclei_Texture_SumEntropy_DNA_10_0 \\\n", - "0 -1.003185 -1.405850 \n", - "1 0.103070 0.986025 \n", - "2 -0.695660 0.100225 \n", - "3 -0.154695 0.165235 \n", - "4 1.013235 0.793675 \n", - "\n", - " Nuclei_Texture_SumEntropy_DNA_20_0 Nuclei_Texture_SumEntropy_DNA_5_0 \\\n", - "0 -1.495100 -0.867225 \n", - "1 1.346200 0.773450 \n", - "2 0.401885 0.114583 \n", - "3 -0.160191 0.242195 \n", - "4 0.682925 1.075500 \n", - "\n", - " Nuclei_Texture_Variance_RNA_10_0 \n", - "0 -0.066115 \n", - "1 -2.749350 \n", - "2 -0.245753 \n", - "3 -0.126886 \n", - "4 0.844115 \n", - "\n", - "[5 rows x 495 columns]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# aggregate replicates by taking the median of each feature\n", - "feature_cols = [c for c in df_consistent.columns if not c.startswith(\"Metadata\")]\n", - "df_consistent = df_consistent.groupby(\n", - " [\"Metadata_broad_sample\", \"Metadata_target\"], as_index=False\n", - ")[feature_cols].median()\n", - "df_consistent[\"Metadata_target\"] = df_consistent[\"Metadata_target\"].str.split(\"|\")\n", - "df_consistent.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we again use metadata columns to define grouping of profiles. Here, we'd like to group those compounds that share a target and assess their similarity against compounds that do not have the same target:\n", - "\n", - "* Two compound profiles are a positive pair if they share the same target. To define that using metadata columns, positive pairs should share the same value in the metadata column that identifies targets (`Metadata_target`). We add this column to a list names `pos_sameby`.\n", - "\n", - "* In this case, profiles that form a positive pair do not need to be different in any of the metatada columns, so we keep `pos_diffby` empty. Although one could define them as being structurally different, for example.\n", - "\n", - "* Two profiles are a negative pair when do not share a common target. That means they should be different in the metadata column that identifies targets (`Metadata_target`).\n", - "\n", - "* Profiles that form a negative pair do not need to be same in any of the metatada columns, so we keep `neg_sameby` empty.\n", - "\n", - "We use `map.multilabel.average_precision` because each compound can have more than one target. If that's not the case, the standard `map.average_precision` should be used instead." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ec8e2c91620549308119846587c003bf", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/1 [00:00\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Metadata_broad_sampleaverage_precisionn_pos_pairsn_total_pairsMetadata_target
52BRD-A69636825-003-04-70.500000142HTR3A
32BRD-A72309220-001-04-10.406071442HTR1A
37BRD-A72309220-001-04-10.142857139HTR1B
39BRD-A72309220-001-04-10.142857139HTR1D
41BRD-A72309220-001-04-10.142857139HTR1E
..................
16BRD-K74363950-004-01-00.105128242CHRM3
19BRD-K74363950-004-01-00.105128242CHRM4
22BRD-K74363950-004-01-00.105128242CHRM5
28BRD-K76908866-001-07-60.500000142ERBB2
61BRD-K81258678-001-01-00.100000142RELA
\n", - "

64 rows × 5 columns

\n", - "" - ], - "text/plain": [ - " Metadata_broad_sample average_precision n_pos_pairs n_total_pairs \\\n", - "52 BRD-A69636825-003-04-7 0.500000 1 42 \n", - "32 BRD-A72309220-001-04-1 0.406071 4 42 \n", - "37 BRD-A72309220-001-04-1 0.142857 1 39 \n", - "39 BRD-A72309220-001-04-1 0.142857 1 39 \n", - "41 BRD-A72309220-001-04-1 0.142857 1 39 \n", - ".. ... ... ... ... \n", - "16 BRD-K74363950-004-01-0 0.105128 2 42 \n", - "19 BRD-K74363950-004-01-0 0.105128 2 42 \n", - "22 BRD-K74363950-004-01-0 0.105128 2 42 \n", - "28 BRD-K76908866-001-07-6 0.500000 1 42 \n", - "61 BRD-K81258678-001-01-0 0.100000 1 42 \n", - "\n", - " Metadata_target \n", - "52 HTR3A \n", - "32 HTR1A \n", - "37 HTR1B \n", - "39 HTR1D \n", - "41 HTR1E \n", - ".. ... \n", - "16 CHRM3 \n", - "19 CHRM4 \n", - "22 CHRM5 \n", - "28 ERBB2 \n", - "61 RELA \n", - "\n", - "[64 rows x 5 columns]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# positive pairs are compounds that share a target\n", - "pos_sameby = [\"Metadata_target\"]\n", - "pos_diffby = []\n", - "\n", - "neg_sameby = []\n", - "# negative pairs are compounds that do not share a target\n", - "neg_diffby = [\"Metadata_target\"]\n", - "\n", - "metadata = df_consistent.filter(regex=\"^Metadata\")\n", - "profiles = df_consistent.filter(regex=\"^(?!Metadata)\").values\n", - "\n", - "target_aps = map.multilabel.average_precision(\n", - " metadata,\n", - " profiles,\n", - " pos_sameby=pos_sameby,\n", - " pos_diffby=pos_diffby,\n", - " neg_sameby=neg_sameby,\n", - " neg_diffby=neg_diffby,\n", - " multilabel_col=\"Metadata_target\",\n", - ")\n", - "target_aps" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Then, we can compute mAP scores and p-values for each target group." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "be9fd249e0b544569e330c1e28bd7ed4", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/15 [00:00\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Metadata_targetmean_average_precisionp_valuecorrected_p_valuebelow_pbelow_corrected_p-log10(p-value)
0ADRA1A0.2500000.1124140.186114FalseFalse0.730220
1ADRA2A0.2500000.1124140.186114FalseFalse0.730220
2AURKA0.6250000.0239760.103896TrueFalse0.983402
3BIRC20.0606620.3804920.471085FalseFalse0.326901
4CHRM10.0984200.4929380.492938FalseFalse0.307208
5CHRM20.0984200.4929380.492938FalseFalse0.307208
6CHRM30.0984200.4929380.492938FalseFalse0.307208
7CHRM40.0984200.4929380.492938FalseFalse0.307208
8CHRM50.0984200.4929380.492938FalseFalse0.307208
9DRD20.7500000.0006700.004355TrueTrue2.361012
\n", - "" - ], - "text/plain": [ - " Metadata_target mean_average_precision p_value corrected_p_value \\\n", - "0 ADRA1A 0.250000 0.112414 0.186114 \n", - "1 ADRA2A 0.250000 0.112414 0.186114 \n", - "2 AURKA 0.625000 0.023976 0.103896 \n", - "3 BIRC2 0.060662 0.380492 0.471085 \n", - "4 CHRM1 0.098420 0.492938 0.492938 \n", - "5 CHRM2 0.098420 0.492938 0.492938 \n", - "6 CHRM3 0.098420 0.492938 0.492938 \n", - "7 CHRM4 0.098420 0.492938 0.492938 \n", - "8 CHRM5 0.098420 0.492938 0.492938 \n", - "9 DRD2 0.750000 0.000670 0.004355 \n", - "\n", - " below_p below_corrected_p -log10(p-value) \n", - "0 False False 0.730220 \n", - "1 False False 0.730220 \n", - "2 True False 0.983402 \n", - "3 False False 0.326901 \n", - "4 False False 0.307208 \n", - "5 False False 0.307208 \n", - "6 False False 0.307208 \n", - "7 False False 0.307208 \n", - "8 False False 0.307208 \n", - "9 True True 2.361012 " - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "target_maps = map.mean_average_precision(\n", - " target_aps, pos_sameby, null_size=1000000, threshold=0.05, seed=0\n", - ")\n", - "target_maps[\"-log10(p-value)\"] = -target_maps[\"corrected_p_value\"].apply(np.log10)\n", - "target_maps.head(10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Similarly, we can plot the results, where groups of compounds targeting the same gene are called consistent if their corrected p-value < 0.05." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGwCAYAAACHJU4LAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA440lEQVR4nO3dd3xUVf7/8fekzKSQhIRQEggBCVIFIqBAXJBeXMuqiKCIfoVdiqyIomJZWHQFZXet2ECB3y5FV8SCCCoSFEV6kCYCoSkdSYeQcn5/uJllTCEzKXOTvJ6Px308mHvPPfOZO8Pcd+6ce6/NGGMEAABgQT7eLgAAAKA4BBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZft4uoCzy8/N19OhRhYSEyGazebscAABQCsYYpaenKzo6Wj4+JR8zqdJB5ejRo4qJifF2GQAAwANHjhxRo0aNSmxTpYNKSEiIpF9faGhoqJerAQAApZGWlqaYmBjnfrwkVTqoFPzcExoaSlABAKCKKc2wDQbTAgAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAFwfPZeuGLXt12ZrvlfDdbq09m+61WggqAADAKSsvX7du3afNaZnKys/XgXPZGrYtWfuyznulHoIKAABw2p6epZ+yc5Rnfn2cLynXGH1xOs0r9RBUAACAk7+PrdA8I8mviPmVgaACAACc2tUKUoeQQPn+97GvpNp+vrq+bm2v1ENQAQAATn4+Nr3TvpmGRdVRu1qB6h8ZpmUdm6u+w9879XjlWQEAgGWF+ftpZssYb5chiSMqAADAwggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsiwTVGbMmCGbzaYJEyZ4uxQAAGARlggqGzdu1BtvvKF27dp5uxQAAGAhXg8qGRkZuuOOOzR79myFh4d7uxwAAGAhXg8q48aN03XXXac+ffpcsm12drbS0tJcJgAAUH35efPJFy9erC1btmjjxo2laj99+nT99a9/reCqAACAVXjtiMqRI0d0//33a8GCBQoICCjVOpMnT1ZqaqpzOnLkSAVXCQAAvMlmjDHeeOIPPvhAf/jDH+Tr6+ucl5eXJ5vNJh8fH2VnZ7ssK0paWprCwsKUmpqq0NDQii4ZAACUA3f231776ad3797avn27y7x77rlHLVu21COPPHLJkAIAAKo/rwWVkJAQtW3b1mVecHCw6tSpU2g+AACombx+1g8AAEBxvHrWz28lJiZ6uwQAAGAhHFEBAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACW5efuCikpKVq6dKm+/vprHTp0SFlZWapbt67i4+PVv39/devWrSLqBAAANVCpj6gcPXpUI0eOVFRUlJ5++mmdO3dOHTp0UO/evdWoUSOtXr1affv2VevWrfXOO+9UZM0AAKCGKPURlfj4eI0YMUKbN29W69ati2xz7tw5ffDBB3rhhRd05MgRPfTQQyX2+dprr+m1117TwYMHJUlt2rTRX/7yFw0cOLD0rwAAAFRbNmOMKU3DM2fOqE6dOqXuuDTtP/74Y/n6+qp58+Yyxmj+/PmaOXOmtm7d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7K4H5P0kvdW2iVfqQfVW6sG0q1at0iOPPKLk5GT17dtXnTp1UnR0tAICAnT27Fnt2rVLa9eu1c6dO3XffffpscceK/IU5vLEYFoA8J7xuw5pc1qmGjrsmntFU9Xy8/V2Sagi3Nl/u33Wz9q1a/XOO+/o66+/1qFDh3Tu3DlFRkYqPj5e/fv31x133FFp11IhqAAAUPVUaFCxEoIKAABVT4VfmRYAAKAyuH168unTp/X2229r3bp1zivTNmjQQF27dtU999yjunXrlnuRAACgZnLriMrGjRt1+eWX66WXXlJYWJi6d++u7t27KywsTC+//LJatmypTZs2VVStAACghnFrjEqXLl3Uvn17vf7667LZbC7LjDEaPXq0vv/+e61bt67cCy0KY1QAAKh6KuwS+tu2bdO8efMKhRRJstlseuCBBxQfH+9etQAAAMVw66efBg0aaMOGDcUu37Bhg+rXr1/mogAAACQ3j6g89NBD+uMf/6jNmzerd+/ezlBy4sQJrVq1SrNnz9bf//73CikUAADUPG4FlXHjxikyMlLPP/+8Xn31VeXl5UmSfH191bFjR82bN0+33XZbhRQKAABqHo8v+JaTk6PTp09LkiIjI+Xv71+uhZUGg2kBAKh6Kmww7cX8/f0VFRXl6eoAAACXVK5Xpt2/f7969epVnl0CAIAarFyDSkZGhtasWVOeXQIAgBrMrZ9+XnrppRKX//zzz2UqBgAA4GJuBZUJEyYoKipKdru9yOUXLlwol6IAAAAkN4NKbGysnn322WJPQU5KSlLHjh3LpTAAAAC3xqh07NhRmzdvLna5zWaTh2c7AwAAFOLWEZVp06YpKyur2OWtW7fWgQMHylwUAACA5GZQad26dYnL/f39FRsbW6aCAAAACpTr6ckAAADlyaMr08bHx8tmsxWab7PZFBAQoLi4ON19993q2bNnif1Mnz5d77//vn744QcFBgaqW7duevbZZ9WiRQtPygIAANWMR0dUBgwYoOTkZAUHB6tnz57q2bOnatWqpf3796tz5846duyY+vTpow8//LDEftasWaNx48bpu+++0+eff66cnBz169dPmZmZHr0YAABQvXh0U8JRo0apcePGevLJJ13mP/300zp06JBmz56tKVOm6JNPPtGmTZtK3e+pU6dUr149rVmzRt27d79ke25KCABA1ePO/tujIyrvvvuuhg4dWmj+7bffrnfffVeSNHToUO3Zs8etflNTUyVJERERRS7Pzs5WWlqaywQAAKovj4JKQECAvv3220Lzv/32WwUEBEiS8vPznf8ujfz8fE2YMEEJCQlq27ZtkW2mT5+usLAw5xQTE+NJ+QAAoIrwaDDt+PHjNXr0aG3evFmdO3eWJG3cuFFz5szRY489JklauXKlOnToUOo+x40bpx07dmjt2rXFtpk8ebImTpzofJyWlkZYAQCgGvNojIokLViwQK+88orz550WLVpo/PjxGjZsmCTp3LlzzrOALuW+++7Thx9+qK+++kpNmzYtdQ2MUQEAoOpxZ//tcVApD8YYjR8/XkuXLlViYqKaN2/u1voEFQAAqh539t8e/fRTYPPmzdq9e7ckqU2bNoqPj3dr/XHjxmnhwoX68MMPFRISouPHj0uSwsLCFBgYWJbSAABANeDREZWTJ0/q9ttvV2JiomrXri1JSklJUc+ePbV48WLVrVu3dE9exEXjJGnu3Lm6++67L7k+R1QAAKh6Kvz05PHjxys9PV07d+7UL7/8ol9++UU7duxQWlqa/vznP5e6H2NMkVNpQgoAAKj+PDqiEhYWpi+++MJ5xk+BDRs2qF+/fkpJSSmv+krEERUAAKqeCj+ikp+fL39//0Lz/f39lZ+f70mXAAAAhXgUVHr16qX7779fR48edc77+eef9cADD6h3797lVhwAAKjZPAoqr7zyitLS0tSkSRM1a9ZMzZo1U9OmTZWWlqaXX365vGsEAAA1lEenJ8fExGjLli364osv9MMPP0iSWrVqpT59+pRrcQAAoGbz6gXfyorBtAAAVD0VcsG3l156qdQFuHOKMgAAQHFKfUSltPfgsdlsSk5OLlNRpcURFQAAqp4KOaJy4MCBIuevXbtWnTp1KtXNBwEAANzh0Vk/Fxs0aJDLacoAAADlpcxBpQqPxQUAABZX5qACAABQUcocVN544w3Vr1+/PGoBAABw4dEF3y42bNiw8qgDAACgEH76AQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAWAJ8+bNU+3atb1dRoVKTEyUzWZTSkpKufR38OBB2Ww2JSUlVUj/3nDttddqwoQJ3i4DFkJQAVAp7r77btlsNtlsNtntdsXFxWnatGnKzc31dmmFNGnSRC+88EK599utWzcdO3ZMYWFh5d53dfH+++/rqaeeKlXbigw1NptNH3zwQYX0fbG//e1v6tatm4KCgooN6gX/by6eFi9eXGK/N9xwgxo3bqyAgABFRUVp+PDhOnr0qEublStXqkuXLgoJCVHdunV1yy236ODBg87lW7duVXx8vGrVqqXrr79ev/zyi3NZbm6uOnbsqA0bNnj82kuLoAKg0gwYMEDHjh3T3r179eCDD2rq1KmaOXOmt8uqNHa7XQ0aNJDNZvN2KZYVERGhkJAQb5dRaS5cuKDBgwdrzJgxJbabO3eujh075pxuuummEtv37NlT7777rvbs2aMlS5Zo//79uvXWW53LDxw4oBtvvFG9evVSUlKSVq5cqdOnT+vmm292thk5cqR69eqlLVu2KDU1Vc8884xz2T/+8Q8lJCToqquu8uyFu8NUYampqUaSSU1N9XYpAC5hxIgR5sYbb3SZ17dvX9OlSxdjjDFz5841YWFhZsWKFaZly5YmODjY9O/f3xw9etRlndmzZ5uWLVsah8NhWrRoYWbNmuVcduDAASPJLFmyxFx77bUmMDDQtGvXznz77bcufbz33numdevWxm63m9jYWPP3v//duaxHjx5GksuUkZFhQkJCzH/+8x+XfpYuXWqCgoJMWlqa87kXLVpkunbtahwOh2nTpo1JTEx0tl+9erWRZM6ePeuct3btWtOjRw8TGBhoateubfr162d++eUXY4wxn376qUlISDBhYWEmIiLCXHfddWbfvn2FXu/WrVsL9V+amouSl5dnnn32WdOsWTNjt9tNTEyMefrpp53Lv//+e9OzZ08TEBBgIiIizKhRo0x6erpzecH7PHPmTNOgQQMTERFhxo4day5cuOBsM2vWLBMXF2ccDoepV6+eueWWW1y2//3333/JtiNGjCj0Ph04cMAYY8z27dvNgAEDTHBwsKlXr5658847zalTp1yeY/z48WbSpEkmPDzc1K9f30yZMsW5PDY21qXf2NjYIrdVeSr4/BdFklm6dGmZ+v/www+NzWZzvg//+c9/jJ+fn8nLy3O2+eijj1zaBAYGmt27dxtjjHn11VfNoEGDjDHG7N+/3zRv3rzYz1BpuLP/JqgAqBRFBZUbbrjBXHnllcaYX7+o/f39TZ8+fczGjRvN5s2bTatWrcywYcOc7f/973+bqKgos2TJEpOcnGyWLFliIiIizLx584wx/9txt2zZ0ixbtszs2bPH3HrrrSY2Ntbk5OQYY4zZtGmT8fHxMdOmTTN79uwxc+fONYGBgWbu3LnGGGPOnDljGjVqZKZNm2aOHTtmjh07ZowxZtSoUc4v6ovrv+uuu1yeu1GjRua9994zu3btMiNHjjQhISHm9OnTxpjCQWXr1q3G4XCYMWPGmKSkJLNjxw7z8ssvO3eq7733nlmyZInZu3ev2bp1q7n++uvNFVdc4dy5lBRUSlNzUR5++GETHh5u5s2bZ/bt22e+/vprM3v2bGOMMRkZGSYqKsrcfPPNZvv27WbVqlWmadOmZsSIES7vc2hoqBk9erTZvXu3+fjjj01QUJB58803jTHGbNy40fj6+pqFCxeagwcPmi1btpgXX3zRuf7FQaWktikpKaZr165m1KhRzvcpNzfXnD171tStW9dMnjzZ7N6922zZssX07dvX9OzZ0+U5QkNDzdSpU82PP/5o5s+fb2w2m/nss8+MMcacPHnSSDJz5841x44dMydPnix2e7Vu3doEBwcXOw0YMKDYdS92qaASHR1t6tSpYzp37mzeeustk5+fX6p+jfn1M33bbbeZhIQE57zk5GRjt9vNnDlzTG5urklJSTGDBw82ffv2dbbp0qWLeemll0xOTo655ZZbzKOPPmqM+fUPjLIGJ4IKAMu5OKjk5+ebzz//3DgcDvPQQw8ZY379opbkcsRg1qxZpn79+s7HzZo1MwsXLnTp96mnnjJdu3Y1xvxvxz1nzhzn8p07dxpJzr8Mhw0b5vJlbIwxkyZNMq1bt3Y+jo2NNc8//7xLm/Xr1xtfX1/nEZ4TJ04YPz8/5xGTgueeMWOGc52cnBzTqFEj8+yzzxpjCgeJoUOHuuw8LuXUqVNGktm+fbvLcxYXVC5V82+lpaUZh8PhDCa/9eabb5rw8HCTkZHhnPfJJ58YHx8fc/z4cWPMr+9zbGysyc3NdbYZPHiwGTJkiDHGmCVLlpjQ0NBi/xq/OKi407bAU089Zfr16+cy78iRI0aS2bNnj3O9a665xqVN586dzSOPPOJ8XNqjGAcPHjR79+4tdvrpp58u2YcxJQeVadOmmbVr15otW7aYGTNmGIfD4RLuivPwww+boKAgI8l06dLFGZgLJCYmmnr16hlfX18jyXTt2tXlaN+OHTtM9+7dTePGjc3QoUNNamqq+X//7/+ZG2+80fz000+mX79+plmzZubxxx8v1Wu8mDv7b8aoAKg0y5YtU61atRQQEKCBAwdqyJAhmjp1qnN5UFCQmjVr5nwcFRWlkydPSpIyMzO1f/9+3XvvvapVq5Zzevrpp7V//36X52nXrp1LH5Kc/ezevVsJCQku7RMSErR3717l5eUVW/tVV12lNm3aaP78+ZKkf//734qNjVX37t1d2nXt2tX5bz8/P3Xq1Em7d+8uss+kpCT17t272Ofcu3evhg4dqssuu0yhoaFq0qSJJOnw4cPFruNJzQV2796t7OzsYmvavXu32rdvr+DgYOe8hIQE5efna8+ePc55bdq0ka+vr/Pxxe9j3759FRsbq8suu0zDhw/XggULlJWVVeTzudO2wLZt27R69WqXz0jLli0lyeVzcvFn5Lc1uiM2NlZxcXHFTg0bNnS7z9968sknlZCQoPj4eD3yyCN6+OGHSzW2a9KkSdq6das+++wz+fr66q677pIxRpJ0/PhxjRo1SiNGjNDGjRu1Zs0a2e123Xrrrc42bdq00Zo1a3To0CEtXLhQOTk5mjJlil555RWNHz9e3bp107Zt2/T+++/r448/LvPrLA5BBUCl6dmzp5KSkrR3716dO3dO8+fPd9np+fv7u7S32WzOL82MjAxJ0uzZs5WUlOScduzYoe+++85lvYv7KRi4mp+fX+b6R44cqXnz5kn6dXDjPffcU6aBsYGBgSUuLzjTYvbs2Vq/fr3Wr18v6dcBmBVR86XqKa2i3seC7R8SEqItW7Zo0aJFioqK0l/+8he1b9++yFOq3WlbICMjQ9dff73LZ6TgM3dxQCupRne0adPGJRT9dho4cKDbfV7K1VdfrZ9++knZ2dkltouMjNTll1+uvn37avHixVq+fLnz/8qsWbMUFham5557TvHx8erevbv+/e9/a9WqVc7P2W9NnDhREyZMUKNGjZSYmKjBgwcrODhY1113nRITE8v7ZToRVABUmuDgYMXFxalx48by8/Nza9369esrOjpaycnJhf5qbdq0aan7adWqlb755huXed98840uv/xy51EAu91e5NGVO++8U4cOHdJLL72kXbt2acSIEYXaXByacnNztXnzZrVq1arIWtq1a6dVq1YVuezMmTPas2ePnnji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NGiQWbt2rTlw4IBJTEw0SUlJlVx59eDu9l+wYIFxOBxmwYIF5sCBA2blypUmKirKPPDAA5VcefWwfPly8/jjj5v333/fSDJLly4tsX1ycrIJCgoyEydONLt27TIvv/yy8fX1NStWrKjQOgkqMFdddZUZN26c83FeXp6Jjo4206dPL9X6ubm5JiQkxMyfP7+iSqzWPNn+ubm5plu3bmbOnDlmxIgRBBUPubvtX3vtNXPZZZeZCxcuVFaJ1Zq723/cuHGmV69eLvMmTpxoEhISKrTOmqA0QeXhhx82bdq0cZk3ZMgQ079//wqszBh++qnhLly4oM2bN6tPnz7OeT4+PurTp4/WrVtXqj6ysrKUk5OjiIiIiiqz2vJ0+0+bNk316tXTvffeWxllVkuebPuPPvpIXbt21bhx41S/fn21bdtWzzzzjPLy8iqr7GrDk+3frVs3bd682fnzUHJyspYvX65BgwZVSs013bp161zeL0nq379/qfcVnqrSNyVE2Z0+fVp5eXmqX7++y/z69evrhx9+KFUfjzzyiKKjowt9gHFpnmz/tWvX6q233lJSUlIlVFh9ebLtk5OT9eWXX+qOO+7Q8uXLtW/fPo0dO1Y5OTmaMmVKZZRdbXiy/YcNG6bTp0/rmmuukTFGubm5Gj16tB577LHKKLnGO378eJHvV1pams6dO6fAwMAKeV6OqKBMZsyYocWLF2vp0qUKCAjwdjnVXnp6uoYPH67Zs2crMjLS2+XUOPn5+apXr57efPNNdezYUUOGDNHjjz+u119/3dul1QiJiYl65pln9Oqrr2rLli16//339cknn+ipp57ydmmoQBxRqeEiIyPl6+urEydOuMw/ceKEGjRoUOK6f//73zVjxgx98cUXateuXUWWWW25u/3379+vgwcP6vrrr3fOy8/PlyT5+flpz549atasWcUWXU148tmPioqSv7+/fH19nfNatWql48eP68KFC7Lb7RVac3XiyfZ/8sknNXz4cI0cOVKSdMUVVygzM1N//OMf9fjjj8vHh7+9K1KDBg2KfL9CQ0Mr7GiKxBGVGs9ut6tjx45atWqVc15+fr5WrVqlrl27Frvec889p6eeekorVqxQp06dKqPUasnd7d+yZUtt375dSUlJzumGG25Qz549lZSUpJiYmMosv0rz5LOfkJCgffv2OcOhJP3444+KiooipLjJk+2flZVVKIwUhEbDbesqXNeuXV3eL0n6/PPPS9xXlIsKHaqLKmHx4sXG4XCYefPmmV27dpk//vGPpnbt2ub48ePGGGOGDx9uHn30UWf7GTNmGLvdbt577z1z7Ngx55Senu6tl1Clubv9f4uzfjzn7rY/fPiwCQkJMffdd5/Zs2ePWbZsmalXr555+umnvfUSqjR3t/+UKVNMSEiIWbRokUlOTjafffaZadasmbntttu89RKqtPT0dLN161azdetWI8n885//NFu3bjWHDh0yxhjz6KOPmuHDhzvbF5yePGnSJLN7924za9YsTk9G5Xn55ZdN48aNjd1uN1dddZX57rvvnMt69OhhRowY4XwcGxtrJBWapkyZUvmFVxPubP/fIqiUjbvb/ttvvzVXX321cTgc5rLLLjN/+9vfTG5ubiVXXX24s/1zcnLM1KlTTbNmzUxAQICJiYkxY8eONWfPnq38wquB1atXF/ldXrDNR4wYYXr06FFonQ4dOhi73W4uu+wyM3fu3Aqv02YMx8sAAIA1MUYFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFgKX1799fvr6+2rhxY6Fld999t2w2m2w2m+x2u+Li4jRt2jTl5uZ6oVIAFYGgAsCyDh8+rG+//Vb33Xef3n777SLbDBgwQMeOHdPevXv14IMPaurUqZo5c2YlVwqgohBUAFS4a6+9VuPHj9eECRMUHh6u+vXra/bs2crMzNQ999yjkJAQxcXF6dNPP3VZb+7cufr973+vMWPGaNGiRTp37lyhvh0Ohxo0aKDY2FiNGTNGffr00UcffVRZLw1ABSOoAKgU8+fPV2RkpDZs2KDx48drzJgxGjx4sLp166YtW7aoX79+Gj58uLKysiRJxhjNnTtXd955p1q2bKm4uDi99957l3yewMBAXbhwoaJfDoBKQlABUCnat2+vJ554Qs2bN9fkyZMVEBCgyMhIjRo1Ss2bN9df/vIXnTlzRt9//70k6YsvvlBWVpb69+8vSbrzzjv11ltvFdu/MUZffPGFVq5cqV69elXKawJQ8QgqACpFu3btnP/29fVVnTp1dMUVVzjn1a9fX5J08uRJSdLbb7+tIUOGyM/PT5I0dOhQffPNN9q/f79Lv8uWLVOtWrUUEBCggQMHasiQIZo6dWoFvxoAlYWgAqBS+Pv7uzy22Wwu82w2myQpPz9fv/zyi5YuXapXX31Vfn5+8vPzU8OGDZWbm1toUG3Pnj2VlJSkvXv36ty5c5o/f76Cg4Mr/gUBqBR+3i4AAH5rwYIFatSokT744AOX+Z999pn+8Y9/aNq0afL19ZUkBQcHKy4uzgtVAqgMBBUAlvPWW2/p1ltvVdu2bV3mx8TEaPLkyVqxYoWuu+46L1UHoDLx0w8AS9m/f7+2bdumW265pdCysLAw9e7du8RBtQCqF5sxxni7CAAAgKJwRAUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFjW/wdjHVoMVQbXvwAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "consistent_ratio = target_maps.below_corrected_p.mean()\n", - "\n", - "plt.scatter(\n", - " data=target_maps,\n", - " x=\"mean_average_precision\",\n", - " y=\"-log10(p-value)\",\n", - " c=\"below_corrected_p\",\n", - " cmap=\"tab10\",\n", - " s=10,\n", - ")\n", - "plt.xlabel(\"mAP\")\n", - "plt.ylabel(\"-log10(p-value)\")\n", - "plt.axhline(-np.log10(0.05), color=\"black\", linestyle=\"--\")\n", - "plt.text(\n", - " 0.5,\n", - " 1.5,\n", - " f\"Phenotypically consistent = {100 * consistent_ratio:.2f}%\",\n", - " va=\"center\",\n", - " ha=\"left\",\n", - ")\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can list compounds that are phenotypically active and consistent.\n", - "\n", - "Note that in multi-label scenario, when each compound can have multiple targets, the same compound can have \"consistent\" response in respect to one target, but not another." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Phenotypically consistent targets: DRD2, EGFR, HTR3A, PSMB1\n", - "Phenotypically consistent compounds: BRD-A69636825-003-04-7, BRD-K50691590-001-02-2, BRD-K60230970-001-10-0, BRD-K70330367-003-07-9, BRD-K70358946-001-15-7, BRD-K70401845-003-09-6, BRD-K70914287-300-02-8\n" - ] - } - ], - "source": [ - "consistent_targets = target_maps.query(\"below_corrected_p\")[\"Metadata_target\"]\n", - "consistent_compounds = df_consistent[\n", - " df_consistent[\"Metadata_target\"].apply(\n", - " lambda x: any(t in x for t in consistent_targets)\n", - " )\n", - "][\"Metadata_broad_sample\"]\n", - "\n", - "print(f\"Phenotypically consistent targets: {consistent_targets.str.cat(sep=', ')}\")\n", - "print(f\"Phenotypically consistent compounds: {consistent_compounds.str.cat(sep=', ')}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] } ], "metadata": { diff --git a/examples/phenotypic_consistency.ipynb b/examples/phenotypic_consistency.ipynb new file mode 100644 index 0000000..4c8dc94 --- /dev/null +++ b/examples/phenotypic_consistency.ipynb @@ -0,0 +1,1251 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# mAP for phenotypic consistency assesement" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from copairs import map" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction\n", + "\n", + "This example demostrates how to use `copairs` to assess phenotypic consistncy of perturbations htat target the same gene against other perturbations.\n", + "\n", + "Phenotypic consistency is assessed by calculating mean average precision (mAP) for the retrieval of phenotypically active samples that share expected biological similarity (such as chemical mechanisms of action and gene-gene relationships) against other phenotypically active samples that are not biologically similar to the query sample.\n", + "\n", + "It aims to answer the question: “How distinctive is this group of perturbations from other phenotypically active samples that are not biologically similar to the query sample?”\n", + "\n", + "The resulting mAP score for a group of perturbations reflects the average extent to which members of this group are more similar to each other compared to other groups (see Figure 1F).\n", + "\n", + "Citation:\n", + "> Kalinin, A. A. et al. A versatile information retrieval framework for evaluating profile strength and similarity. bioRxiv, 2024-04, (2024)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load data\n", + "\n", + "Assessing phenotypic consistency relies on data and results from the [Phenotypic activity](./phenotypic_activity.ipynb) example, so run that one first if you haven't." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.read_csv(\"data/2016_04_01_a549_48hr_batch1_plateSQ00014812.csv\")\n", + "activity_map = pd.read_csv(\n", + " \"data/activity_map.csv\"\n", + ") # load mAP scores for phenotypic activity" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Assessing phenotypic consistency of compounds grouped by targets\n", + "\n", + "First, we are going to filter out compounds that were not phenotypically active using mAP p-values from the previous section.\n", + "\n", + "Next, we will aggregate each compound’s replicate profiles into a \"consensus\" profile by taking the median of each feature to reduce profile noise and improve computational efficiency." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Metadata_plate_map_nameMetadata_broad_sampleMetadata_mg_per_mlMetadata_mmoles_per_literMetadata_solventMetadata_pert_idMetadata_pert_mfc_idMetadata_pert_wellMetadata_pert_id_vendorMetadata_cell_id...Nuclei_Texture_InverseDifferenceMoment_AGP_5_0Nuclei_Texture_InverseDifferenceMoment_DNA_20_0Nuclei_Texture_InverseDifferenceMoment_ER_5_0Nuclei_Texture_InverseDifferenceMoment_Mito_10_0Nuclei_Texture_InverseDifferenceMoment_Mito_5_0Nuclei_Texture_SumAverage_RNA_5_0Nuclei_Texture_SumEntropy_DNA_10_0Nuclei_Texture_SumEntropy_DNA_20_0Nuclei_Texture_SumEntropy_DNA_5_0Nuclei_Texture_Variance_RNA_10_0
6C-7161-01-LM6-022BRD-K74363950-004-01-05.65560010.000000DMSOBRD-K74363950BRD-K74363950-004-01-0A07NaNA549...-0.51038-0.764021.616400-0.49600-0.4813602.4211001.107901.138201.143200.329230
7C-7161-01-LM6-022BRD-K74363950-004-01-01.8852003.333300DMSOBRD-K74363950BRD-K74363950-004-01-0A08NaNA549...-0.23602-0.411290.3049600.478840.005852-0.7103300.41986-0.238880.54949-0.092826
8C-7161-01-LM6-022BRD-K74363950-004-01-00.6284001.111100DMSOBRD-K74363950BRD-K74363950-004-01-0A09NaNA549...-0.52939-0.547270.7225700.733990.2238500.0358420.333180.390640.42969-0.811390
9C-7161-01-LM6-022BRD-K74363950-004-01-00.2094700.370370DMSOBRD-K74363950BRD-K74363950-004-01-0A10NaNA549...-0.58515-0.415330.0448740.763740.062913-0.6568500.18149-0.109600.48699-0.345260
10C-7161-01-LM6-022BRD-K74363950-004-01-00.0698230.123460DMSOBRD-K74363950BRD-K74363950-004-01-0A11NaNA549...-0.52686-0.578230.5916100.851840.5603700.0391840.598640.441230.75783-0.018031
11C-7161-01-LM6-022BRD-K74363950-004-01-00.0232740.041152DMSOBRD-K74363950BRD-K74363950-004-01-0A12NaNA549...-0.48060-1.472200.8141500.794630.0892490.0722400.918280.396261.09120-0.243750
12C-7161-01-LM6-022BRD-K75958547-238-01-04.61540010.000000DMSOBRD-K75958547BRD-K75958547-238-01-0A13NaNA549...-5.89680-0.97404-5.025000-10.41400-6.0675007.6257003.318303.27410-2.122402.299300
\n", + "

7 rows × 519 columns

\n", + "
" + ], + "text/plain": [ + " Metadata_plate_map_name Metadata_broad_sample Metadata_mg_per_ml \\\n", + "6 C-7161-01-LM6-022 BRD-K74363950-004-01-0 5.655600 \n", + "7 C-7161-01-LM6-022 BRD-K74363950-004-01-0 1.885200 \n", + "8 C-7161-01-LM6-022 BRD-K74363950-004-01-0 0.628400 \n", + "9 C-7161-01-LM6-022 BRD-K74363950-004-01-0 0.209470 \n", + "10 C-7161-01-LM6-022 BRD-K74363950-004-01-0 0.069823 \n", + "11 C-7161-01-LM6-022 BRD-K74363950-004-01-0 0.023274 \n", + "12 C-7161-01-LM6-022 BRD-K75958547-238-01-0 4.615400 \n", + "\n", + " Metadata_mmoles_per_liter Metadata_solvent Metadata_pert_id \\\n", + "6 10.000000 DMSO BRD-K74363950 \n", + "7 3.333300 DMSO BRD-K74363950 \n", + "8 1.111100 DMSO BRD-K74363950 \n", + "9 0.370370 DMSO BRD-K74363950 \n", + "10 0.123460 DMSO BRD-K74363950 \n", + "11 0.041152 DMSO BRD-K74363950 \n", + "12 10.000000 DMSO BRD-K75958547 \n", + "\n", + " Metadata_pert_mfc_id Metadata_pert_well Metadata_pert_id_vendor \\\n", + "6 BRD-K74363950-004-01-0 A07 NaN \n", + "7 BRD-K74363950-004-01-0 A08 NaN \n", + "8 BRD-K74363950-004-01-0 A09 NaN \n", + "9 BRD-K74363950-004-01-0 A10 NaN \n", + "10 BRD-K74363950-004-01-0 A11 NaN \n", + "11 BRD-K74363950-004-01-0 A12 NaN \n", + "12 BRD-K75958547-238-01-0 A13 NaN \n", + "\n", + " Metadata_cell_id ... Nuclei_Texture_InverseDifferenceMoment_AGP_5_0 \\\n", + "6 A549 ... -0.51038 \n", + "7 A549 ... -0.23602 \n", + "8 A549 ... -0.52939 \n", + "9 A549 ... -0.58515 \n", + "10 A549 ... -0.52686 \n", + "11 A549 ... -0.48060 \n", + "12 A549 ... -5.89680 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_DNA_20_0 \\\n", + "6 -0.76402 \n", + "7 -0.41129 \n", + "8 -0.54727 \n", + "9 -0.41533 \n", + "10 -0.57823 \n", + "11 -1.47220 \n", + "12 -0.97404 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_ER_5_0 \\\n", + "6 1.616400 \n", + "7 0.304960 \n", + "8 0.722570 \n", + "9 0.044874 \n", + "10 0.591610 \n", + "11 0.814150 \n", + "12 -5.025000 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_Mito_10_0 \\\n", + "6 -0.49600 \n", + "7 0.47884 \n", + "8 0.73399 \n", + "9 0.76374 \n", + "10 0.85184 \n", + "11 0.79463 \n", + "12 -10.41400 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_Mito_5_0 \\\n", + "6 -0.481360 \n", + "7 0.005852 \n", + "8 0.223850 \n", + "9 0.062913 \n", + "10 0.560370 \n", + "11 0.089249 \n", + "12 -6.067500 \n", + "\n", + " Nuclei_Texture_SumAverage_RNA_5_0 Nuclei_Texture_SumEntropy_DNA_10_0 \\\n", + "6 2.421100 1.10790 \n", + "7 -0.710330 0.41986 \n", + "8 0.035842 0.33318 \n", + "9 -0.656850 0.18149 \n", + "10 0.039184 0.59864 \n", + "11 0.072240 0.91828 \n", + "12 7.625700 3.31830 \n", + "\n", + " Nuclei_Texture_SumEntropy_DNA_20_0 Nuclei_Texture_SumEntropy_DNA_5_0 \\\n", + "6 1.13820 1.14320 \n", + "7 -0.23888 0.54949 \n", + "8 0.39064 0.42969 \n", + "9 -0.10960 0.48699 \n", + "10 0.44123 0.75783 \n", + "11 0.39626 1.09120 \n", + "12 3.27410 -2.12240 \n", + "\n", + " Nuclei_Texture_Variance_RNA_10_0 \n", + "6 0.329230 \n", + "7 -0.092826 \n", + "8 -0.811390 \n", + "9 -0.345260 \n", + "10 -0.018031 \n", + "11 -0.243750 \n", + "12 2.299300 \n", + "\n", + "[7 rows x 519 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# only keep active compounds, i.e. those with corrected p-value < 0.05\n", + "active_compounds = activity_map.query(\"below_corrected_p\")[\"Metadata_broad_sample\"]\n", + "df_active = df.query(\"Metadata_broad_sample in @active_compounds\")\n", + "df_active.head(7)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Metadata_broad_sampleMetadata_targetCells_AreaShape_EccentricityCells_AreaShape_ExtentCells_AreaShape_FormFactorCells_AreaShape_OrientationCells_AreaShape_SolidityCells_AreaShape_Zernike_0_0Cells_AreaShape_Zernike_1_1Cells_AreaShape_Zernike_2_0...Nuclei_Texture_InverseDifferenceMoment_AGP_5_0Nuclei_Texture_InverseDifferenceMoment_DNA_20_0Nuclei_Texture_InverseDifferenceMoment_ER_5_0Nuclei_Texture_InverseDifferenceMoment_Mito_10_0Nuclei_Texture_InverseDifferenceMoment_Mito_5_0Nuclei_Texture_SumAverage_RNA_5_0Nuclei_Texture_SumEntropy_DNA_10_0Nuclei_Texture_SumEntropy_DNA_20_0Nuclei_Texture_SumEntropy_DNA_5_0Nuclei_Texture_Variance_RNA_10_0
0BRD-A69636825-003-04-7[CACNA1C, CACNA1S, CACNA2D1, CACNG1, HTR3A, KC...-0.3263650.6516100.2112800.0924120.4569150.4865150.4355450.863160...0.1752000.557360-0.8594650.4090450.201909-1.003185-1.405850-1.495100-0.867225-0.066115
1BRD-A69815203-001-07-6[ABCB11, CAMLG, FPR1, PPIA, PPIF, PPP3CA, PPP3...2.487450-2.8727500.616635-0.451942-2.260100-3.3009000.316320-1.825400...-2.681800-0.197230-4.7173500.6441701.3241000.1030700.9860251.3462000.773450-2.749350
2BRD-A70858459-001-01-7[ESR1, ESR2, MAP1A, MAP2]-0.9202101.4615500.445630-0.3942351.5284501.116100-0.0549901.061270...0.2388750.3264750.0645630.1876460.200447-0.6956600.1002250.4018850.114583-0.245753
3BRD-A72309220-001-04-1[HTR1A, HTR1B, HTR1D, HTR1E, HTR1F, HTR2A, HTR...0.0454350.0997550.1036280.592620-0.3522000.202930-0.059855-0.353755...1.069575-0.475915-0.1740020.2179650.090715-0.1546950.165235-0.1601910.242195-0.126886
4BRD-A73368467-003-17-6[HRH1]-0.062074-0.3148200.526190-0.502485-0.444675-0.1912250.1450190.018870...0.527805-1.2042500.615420-0.1876450.3218801.0132350.7936750.6829251.0755000.844115
\n", + "

5 rows × 495 columns

\n", + "
" + ], + "text/plain": [ + " Metadata_broad_sample Metadata_target \\\n", + "0 BRD-A69636825-003-04-7 [CACNA1C, CACNA1S, CACNA2D1, CACNG1, HTR3A, KC... \n", + "1 BRD-A69815203-001-07-6 [ABCB11, CAMLG, FPR1, PPIA, PPIF, PPP3CA, PPP3... \n", + "2 BRD-A70858459-001-01-7 [ESR1, ESR2, MAP1A, MAP2] \n", + "3 BRD-A72309220-001-04-1 [HTR1A, HTR1B, HTR1D, HTR1E, HTR1F, HTR2A, HTR... \n", + "4 BRD-A73368467-003-17-6 [HRH1] \n", + "\n", + " Cells_AreaShape_Eccentricity Cells_AreaShape_Extent \\\n", + "0 -0.326365 0.651610 \n", + "1 2.487450 -2.872750 \n", + "2 -0.920210 1.461550 \n", + "3 0.045435 0.099755 \n", + "4 -0.062074 -0.314820 \n", + "\n", + " Cells_AreaShape_FormFactor Cells_AreaShape_Orientation \\\n", + "0 0.211280 0.092412 \n", + "1 0.616635 -0.451942 \n", + "2 0.445630 -0.394235 \n", + "3 0.103628 0.592620 \n", + "4 0.526190 -0.502485 \n", + "\n", + " Cells_AreaShape_Solidity Cells_AreaShape_Zernike_0_0 \\\n", + "0 0.456915 0.486515 \n", + "1 -2.260100 -3.300900 \n", + "2 1.528450 1.116100 \n", + "3 -0.352200 0.202930 \n", + "4 -0.444675 -0.191225 \n", + "\n", + " Cells_AreaShape_Zernike_1_1 Cells_AreaShape_Zernike_2_0 ... \\\n", + "0 0.435545 0.863160 ... \n", + "1 0.316320 -1.825400 ... \n", + "2 -0.054990 1.061270 ... \n", + "3 -0.059855 -0.353755 ... \n", + "4 0.145019 0.018870 ... \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_AGP_5_0 \\\n", + "0 0.175200 \n", + "1 -2.681800 \n", + "2 0.238875 \n", + "3 1.069575 \n", + "4 0.527805 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_DNA_20_0 \\\n", + "0 0.557360 \n", + "1 -0.197230 \n", + "2 0.326475 \n", + "3 -0.475915 \n", + "4 -1.204250 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_ER_5_0 \\\n", + "0 -0.859465 \n", + "1 -4.717350 \n", + "2 0.064563 \n", + "3 -0.174002 \n", + "4 0.615420 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_Mito_10_0 \\\n", + "0 0.409045 \n", + "1 0.644170 \n", + "2 0.187646 \n", + "3 0.217965 \n", + "4 -0.187645 \n", + "\n", + " Nuclei_Texture_InverseDifferenceMoment_Mito_5_0 \\\n", + "0 0.201909 \n", + "1 1.324100 \n", + "2 0.200447 \n", + "3 0.090715 \n", + "4 0.321880 \n", + "\n", + " Nuclei_Texture_SumAverage_RNA_5_0 Nuclei_Texture_SumEntropy_DNA_10_0 \\\n", + "0 -1.003185 -1.405850 \n", + "1 0.103070 0.986025 \n", + "2 -0.695660 0.100225 \n", + "3 -0.154695 0.165235 \n", + "4 1.013235 0.793675 \n", + "\n", + " Nuclei_Texture_SumEntropy_DNA_20_0 Nuclei_Texture_SumEntropy_DNA_5_0 \\\n", + "0 -1.495100 -0.867225 \n", + "1 1.346200 0.773450 \n", + "2 0.401885 0.114583 \n", + "3 -0.160191 0.242195 \n", + "4 0.682925 1.075500 \n", + "\n", + " Nuclei_Texture_Variance_RNA_10_0 \n", + "0 -0.066115 \n", + "1 -2.749350 \n", + "2 -0.245753 \n", + "3 -0.126886 \n", + "4 0.844115 \n", + "\n", + "[5 rows x 495 columns]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# aggregate replicates by taking the median of each feature\n", + "feature_cols = [c for c in df_active.columns if not c.startswith(\"Metadata\")]\n", + "df_active = df_active.groupby(\n", + " [\"Metadata_broad_sample\", \"Metadata_target\"], as_index=False\n", + ")[feature_cols].median()\n", + "df_active[\"Metadata_target\"] = df_active[\"Metadata_target\"].str.split(\"|\")\n", + "df_active.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we again use metadata columns to define grouping of profiles. Here, we'd like to group those compounds that share a target and assess their similarity against compounds that do not have the same target:\n", + "\n", + "* Two compound profiles are a positive pair if they share the same target. To define that using metadata columns, positive pairs should share the same value in the metadata column that identifies targets (`Metadata_target`). We add this column to a list names `pos_sameby`.\n", + "\n", + "* In this case, profiles that form a positive pair do not need to be different in any of the metatada columns, so we keep `pos_diffby` empty. Although one could define them as being structurally different, for example.\n", + "\n", + "* Two profiles are a negative pair when do not share a common target. That means they should be different in the metadata column that identifies targets (`Metadata_target`).\n", + "\n", + "* Profiles that form a negative pair do not need to be same in any of the metatada columns, so we keep `neg_sameby` empty.\n", + "\n", + "We use `map.multilabel.average_precision` because each compound can have more than one target. If that's not the case, the standard `map.average_precision` should be used instead." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "72e631ce67b44d2f890735cc44c480d4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Metadata_broad_sampleaverage_precisionn_pos_pairsn_total_pairsMetadata_target
52BRD-A69636825-003-04-70.500000142HTR3A
32BRD-A72309220-001-04-10.406071442HTR1A
37BRD-A72309220-001-04-10.142857139HTR1B
39BRD-A72309220-001-04-10.142857139HTR1D
41BRD-A72309220-001-04-10.142857139HTR1E
..................
16BRD-K74363950-004-01-00.105128242CHRM3
19BRD-K74363950-004-01-00.105128242CHRM4
22BRD-K74363950-004-01-00.105128242CHRM5
28BRD-K76908866-001-07-60.500000142ERBB2
61BRD-K81258678-001-01-00.100000142RELA
\n", + "

64 rows × 5 columns

\n", + "" + ], + "text/plain": [ + " Metadata_broad_sample average_precision n_pos_pairs n_total_pairs \\\n", + "52 BRD-A69636825-003-04-7 0.500000 1 42 \n", + "32 BRD-A72309220-001-04-1 0.406071 4 42 \n", + "37 BRD-A72309220-001-04-1 0.142857 1 39 \n", + "39 BRD-A72309220-001-04-1 0.142857 1 39 \n", + "41 BRD-A72309220-001-04-1 0.142857 1 39 \n", + ".. ... ... ... ... \n", + "16 BRD-K74363950-004-01-0 0.105128 2 42 \n", + "19 BRD-K74363950-004-01-0 0.105128 2 42 \n", + "22 BRD-K74363950-004-01-0 0.105128 2 42 \n", + "28 BRD-K76908866-001-07-6 0.500000 1 42 \n", + "61 BRD-K81258678-001-01-0 0.100000 1 42 \n", + "\n", + " Metadata_target \n", + "52 HTR3A \n", + "32 HTR1A \n", + "37 HTR1B \n", + "39 HTR1D \n", + "41 HTR1E \n", + ".. ... \n", + "16 CHRM3 \n", + "19 CHRM4 \n", + "22 CHRM5 \n", + "28 ERBB2 \n", + "61 RELA \n", + "\n", + "[64 rows x 5 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# positive pairs are compounds that share a target\n", + "pos_sameby = [\"Metadata_target\"]\n", + "pos_diffby = []\n", + "\n", + "neg_sameby = []\n", + "# negative pairs are compounds that do not share a target\n", + "neg_diffby = [\"Metadata_target\"]\n", + "\n", + "metadata = df_active.filter(regex=\"^Metadata\")\n", + "profiles = df_active.filter(regex=\"^(?!Metadata)\").values\n", + "\n", + "target_aps = map.multilabel.average_precision(\n", + " metadata,\n", + " profiles,\n", + " pos_sameby=pos_sameby,\n", + " pos_diffby=pos_diffby,\n", + " neg_sameby=neg_sameby,\n", + " neg_diffby=neg_diffby,\n", + " multilabel_col=\"Metadata_target\",\n", + ")\n", + "target_aps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then, we can compute mAP scores and p-values for each target group." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f03f87b87d1c45549ec70867a939d998", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/15 [00:00\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Metadata_targetmean_average_precisionp_valuecorrected_p_valuebelow_pbelow_corrected_p-log10(p-value)
0ADRA1A0.2500000.1124140.186114FalseFalse0.730220
1ADRA2A0.2500000.1124140.186114FalseFalse0.730220
2AURKA0.6250000.0239760.103896TrueFalse0.983402
3BIRC20.0606620.3804920.471085FalseFalse0.326901
4CHRM10.0984200.4929380.492938FalseFalse0.307208
5CHRM20.0984200.4929380.492938FalseFalse0.307208
6CHRM30.0984200.4929380.492938FalseFalse0.307208
7CHRM40.0984200.4929380.492938FalseFalse0.307208
8CHRM50.0984200.4929380.492938FalseFalse0.307208
9DRD20.7500000.0006700.004355TrueTrue2.361012
\n", + "" + ], + "text/plain": [ + " Metadata_target mean_average_precision p_value corrected_p_value \\\n", + "0 ADRA1A 0.250000 0.112414 0.186114 \n", + "1 ADRA2A 0.250000 0.112414 0.186114 \n", + "2 AURKA 0.625000 0.023976 0.103896 \n", + "3 BIRC2 0.060662 0.380492 0.471085 \n", + "4 CHRM1 0.098420 0.492938 0.492938 \n", + "5 CHRM2 0.098420 0.492938 0.492938 \n", + "6 CHRM3 0.098420 0.492938 0.492938 \n", + "7 CHRM4 0.098420 0.492938 0.492938 \n", + "8 CHRM5 0.098420 0.492938 0.492938 \n", + "9 DRD2 0.750000 0.000670 0.004355 \n", + "\n", + " below_p below_corrected_p -log10(p-value) \n", + "0 False False 0.730220 \n", + "1 False False 0.730220 \n", + "2 True False 0.983402 \n", + "3 False False 0.326901 \n", + "4 False False 0.307208 \n", + "5 False False 0.307208 \n", + "6 False False 0.307208 \n", + "7 False False 0.307208 \n", + "8 False False 0.307208 \n", + "9 True True 2.361012 " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_maps = map.mean_average_precision(\n", + " target_aps, pos_sameby, null_size=1000000, threshold=0.05, seed=0\n", + ")\n", + "target_maps[\"-log10(p-value)\"] = -target_maps[\"corrected_p_value\"].apply(np.log10)\n", + "target_maps.head(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similarly, we can plot the results, where groups of compounds targeting the same gene are called consistent if their corrected p-value < 0.05." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGwCAYAAACHJU4LAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA440lEQVR4nO3dd3xUVf7/8fekzKSQhIRQEggBCVIFIqBAXJBeXMuqiKCIfoVdiqyIomJZWHQFZXet2ECB3y5FV8SCCCoSFEV6kCYCoSkdSYeQcn5/uJllTCEzKXOTvJ6Px308mHvPPfOZO8Pcd+6ce6/NGGMEAABgQT7eLgAAAKA4BBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZBBUAAGBZft4uoCzy8/N19OhRhYSEyGazebscAABQCsYYpaenKzo6Wj4+JR8zqdJB5ejRo4qJifF2GQAAwANHjhxRo0aNSmxTpYNKSEiIpF9faGhoqJerAQAApZGWlqaYmBjnfrwkVTqoFPzcExoaSlABAKCKKc2wDQbTAgAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAyyKoAAAAFwfPZeuGLXt12ZrvlfDdbq09m+61WggqAADAKSsvX7du3afNaZnKys/XgXPZGrYtWfuyznulHoIKAABw2p6epZ+yc5Rnfn2cLynXGH1xOs0r9RBUAACAk7+PrdA8I8mviPmVgaACAACc2tUKUoeQQPn+97GvpNp+vrq+bm2v1ENQAQAATn4+Nr3TvpmGRdVRu1qB6h8ZpmUdm6u+w9879XjlWQEAgGWF+ftpZssYb5chiSMqAADAwggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsggqAADAsiwTVGbMmCGbzaYJEyZ4uxQAAGARlggqGzdu1BtvvKF27dp5uxQAAGAhXg8qGRkZuuOOOzR79myFh4d7uxwAAGAhXg8q48aN03XXXac+ffpcsm12drbS0tJcJgAAUH35efPJFy9erC1btmjjxo2laj99+nT99a9/reCqAACAVXjtiMqRI0d0//33a8GCBQoICCjVOpMnT1ZqaqpzOnLkSAVXCQAAvMlmjDHeeOIPPvhAf/jDH+Tr6+ucl5eXJ5vNJh8fH2VnZ7ssK0paWprCwsKUmpqq0NDQii4ZAACUA3f231776ad3797avn27y7x77rlHLVu21COPPHLJkAIAAKo/rwWVkJAQtW3b1mVecHCw6tSpU2g+AACombx+1g8AAEBxvHrWz28lJiZ6uwQAAGAhHFEBAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACWRVABAACW5efuCikpKVq6dKm+/vprHTp0SFlZWapbt67i4+PVv39/devWrSLqBAAANVCpj6gcPXpUI0eOVFRUlJ5++mmdO3dOHTp0UO/evdWoUSOtXr1affv2VevWrfXOO+9UZM0AAKCGKPURlfj4eI0YMUKbN29W69ati2xz7tw5ffDBB3rhhRd05MgRPfTQQyX2+dprr+m1117TwYMHJUlt2rTRX/7yFw0cOLD0rwAAAFRbNmOMKU3DM2fOqE6dOqXuuDTtP/74Y/n6+qp58+Yyxmj+/PmaOXOmtm7d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7K4H5P0kvdW2iVfqQfVW6sG0q1at0iOPPKLk5GT17dtXnTp1UnR0tAICAnT27Fnt2rVLa9eu1c6dO3XffffpscceK/IU5vLEYFoA8J7xuw5pc1qmGjrsmntFU9Xy8/V2Sagi3Nl/u33Wz9q1a/XOO+/o66+/1qFDh3Tu3DlFRkYqPj5e/fv31x133FFp11IhqAAAUPVUaFCxEoIKAABVT4VfmRYAAKAyuH168unTp/X2229r3bp1zivTNmjQQF27dtU999yjunXrlnuRAACgZnLriMrGjRt1+eWX66WXXlJYWJi6d++u7t27KywsTC+//LJatmypTZs2VVStAACghnFrjEqXLl3Uvn17vf7667LZbC7LjDEaPXq0vv/+e61bt67cCy0KY1QAAKh6KuwS+tu2bdO8efMKhRRJstlseuCBBxQfH+9etQAAAMVw66efBg0aaMOGDcUu37Bhg+rXr1/mogAAACQ3j6g89NBD+uMf/6jNmzerd+/ezlBy4sQJrVq1SrNnz9bf//73CikUAADUPG4FlXHjxikyMlLPP/+8Xn31VeXl5UmSfH191bFjR82bN0+33XZbhRQKAABqHo8v+JaTk6PTp09LkiIjI+Xv71+uhZUGg2kBAKh6Kmww7cX8/f0VFRXl6eoAAACXVK5Xpt2/f7969epVnl0CAIAarFyDSkZGhtasWVOeXQIAgBrMrZ9+XnrppRKX//zzz2UqBgAA4GJuBZUJEyYoKipKdru9yOUXLlwol6IAAAAkN4NKbGysnn322WJPQU5KSlLHjh3LpTAAAAC3xqh07NhRmzdvLna5zWaTh2c7AwAAFOLWEZVp06YpKyur2OWtW7fWgQMHylwUAACA5GZQad26dYnL/f39FRsbW6aCAAAACpTr6ckAAADlyaMr08bHx8tmsxWab7PZFBAQoLi4ON19993q2bNnif1Mnz5d77//vn744QcFBgaqW7duevbZZ9WiRQtPygIAANWMR0dUBgwYoOTkZAUHB6tnz57q2bOnatWqpf3796tz5846duyY+vTpow8//LDEftasWaNx48bpu+++0+eff66cnBz169dPmZmZHr0YAABQvXh0U8JRo0apcePGevLJJ13mP/300zp06JBmz56tKVOm6JNPPtGmTZtK3e+pU6dUr149rVmzRt27d79ke25KCABA1ePO/tujIyrvvvuuhg4dWmj+7bffrnfffVeSNHToUO3Zs8etflNTUyVJERERRS7Pzs5WWlqaywQAAKovj4JKQECAvv3220Lzv/32WwUEBEiS8vPznf8ujfz8fE2YMEEJCQlq27ZtkW2mT5+usLAw5xQTE+NJ+QAAoIrwaDDt+PHjNXr0aG3evFmdO3eWJG3cuFFz5szRY489JklauXKlOnToUOo+x40bpx07dmjt2rXFtpk8ebImTpzofJyWlkZYAQCgGvNojIokLViwQK+88orz550WLVpo/PjxGjZsmCTp3LlzzrOALuW+++7Thx9+qK+++kpNmzYtdQ2MUQEAoOpxZ//tcVApD8YYjR8/XkuXLlViYqKaN2/u1voEFQAAqh539t8e/fRTYPPmzdq9e7ckqU2bNoqPj3dr/XHjxmnhwoX68MMPFRISouPHj0uSwsLCFBgYWJbSAABANeDREZWTJ0/q9ttvV2JiomrXri1JSklJUc+ePbV48WLVrVu3dE9exEXjJGnu3Lm6++67L7k+R1QAAKh6Kvz05PHjxys9PV07d+7UL7/8ol9++UU7duxQWlqa/vznP5e6H2NMkVNpQgoAAKj+PDqiEhYWpi+++MJ5xk+BDRs2qF+/fkpJSSmv+krEERUAAKqeCj+ikp+fL39//0Lz/f39lZ+f70mXAAAAhXgUVHr16qX7779fR48edc77+eef9cADD6h3797lVhwAAKjZPAoqr7zyitLS0tSkSRM1a9ZMzZo1U9OmTZWWlqaXX365vGsEAAA1lEenJ8fExGjLli364osv9MMPP0iSWrVqpT59+pRrcQAAoGbz6gXfyorBtAAAVD0VcsG3l156qdQFuHOKMgAAQHFKfUSltPfgsdlsSk5OLlNRpcURFQAAqp4KOaJy4MCBIuevXbtWnTp1KtXNBwEAANzh0Vk/Fxs0aJDLacoAAADlpcxBpQqPxQUAABZX5qACAABQUcocVN544w3Vr1+/PGoBAABw4dEF3y42bNiw8qgDAACgEH76AQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAQAAlkVQAWAJ8+bNU+3atb1dRoVKTEyUzWZTSkpKufR38OBB2Ww2JSUlVUj/3nDttddqwoQJ3i4DFkJQAVAp7r77btlsNtlsNtntdsXFxWnatGnKzc31dmmFNGnSRC+88EK599utWzcdO3ZMYWFh5d53dfH+++/rqaeeKlXbigw1NptNH3zwQYX0fbG//e1v6tatm4KCgooN6gX/by6eFi9eXGK/N9xwgxo3bqyAgABFRUVp+PDhOnr0qEublStXqkuXLgoJCVHdunV1yy236ODBg87lW7duVXx8vGrVqqXrr79ev/zyi3NZbm6uOnbsqA0bNnj82kuLoAKg0gwYMEDHjh3T3r179eCDD2rq1KmaOXOmt8uqNHa7XQ0aNJDNZvN2KZYVERGhkJAQb5dRaS5cuKDBgwdrzJgxJbabO3eujh075pxuuummEtv37NlT7777rvbs2aMlS5Zo//79uvXWW53LDxw4oBtvvFG9evVSUlKSVq5cqdOnT+vmm292thk5cqR69eqlLVu2KDU1Vc8884xz2T/+8Q8lJCToqquu8uyFu8NUYampqUaSSU1N9XYpAC5hxIgR5sYbb3SZ17dvX9OlSxdjjDFz5841YWFhZsWKFaZly5YmODjY9O/f3xw9etRlndmzZ5uWLVsah8NhWrRoYWbNmuVcduDAASPJLFmyxFx77bUmMDDQtGvXznz77bcufbz33numdevWxm63m9jYWPP3v//duaxHjx5GksuUkZFhQkJCzH/+8x+XfpYuXWqCgoJMWlqa87kXLVpkunbtahwOh2nTpo1JTEx0tl+9erWRZM6ePeuct3btWtOjRw8TGBhoateubfr162d++eUXY4wxn376qUlISDBhYWEmIiLCXHfddWbfvn2FXu/WrVsL9V+amouSl5dnnn32WdOsWTNjt9tNTEyMefrpp53Lv//+e9OzZ08TEBBgIiIizKhRo0x6erpzecH7PHPmTNOgQQMTERFhxo4day5cuOBsM2vWLBMXF2ccDoepV6+eueWWW1y2//3333/JtiNGjCj0Ph04cMAYY8z27dvNgAEDTHBwsKlXr5658847zalTp1yeY/z48WbSpEkmPDzc1K9f30yZMsW5PDY21qXf2NjYIrdVeSr4/BdFklm6dGmZ+v/www+NzWZzvg//+c9/jJ+fn8nLy3O2+eijj1zaBAYGmt27dxtjjHn11VfNoEGDjDHG7N+/3zRv3rzYz1BpuLP/JqgAqBRFBZUbbrjBXHnllcaYX7+o/f39TZ8+fczGjRvN5s2bTatWrcywYcOc7f/973+bqKgos2TJEpOcnGyWLFliIiIizLx584wx/9txt2zZ0ixbtszs2bPH3HrrrSY2Ntbk5OQYY4zZtGmT8fHxMdOmTTN79uwxc+fONYGBgWbu3LnGGGPOnDljGjVqZKZNm2aOHTtmjh07ZowxZtSoUc4v6ovrv+uuu1yeu1GjRua9994zu3btMiNHjjQhISHm9OnTxpjCQWXr1q3G4XCYMWPGmKSkJLNjxw7z8ssvO3eq7733nlmyZInZu3ev2bp1q7n++uvNFVdc4dy5lBRUSlNzUR5++GETHh5u5s2bZ/bt22e+/vprM3v2bGOMMRkZGSYqKsrcfPPNZvv27WbVqlWmadOmZsSIES7vc2hoqBk9erTZvXu3+fjjj01QUJB58803jTHGbNy40fj6+pqFCxeagwcPmi1btpgXX3zRuf7FQaWktikpKaZr165m1KhRzvcpNzfXnD171tStW9dMnjzZ7N6922zZssX07dvX9OzZ0+U5QkNDzdSpU82PP/5o5s+fb2w2m/nss8+MMcacPHnSSDJz5841x44dMydPnix2e7Vu3doEBwcXOw0YMKDYdS92qaASHR1t6tSpYzp37mzeeustk5+fX6p+jfn1M33bbbeZhIQE57zk5GRjt9vNnDlzTG5urklJSTGDBw82ffv2dbbp0qWLeemll0xOTo655ZZbzKOPPmqM+fUPjLIGJ4IKAMu5OKjk5+ebzz//3DgcDvPQQw8ZY379opbkcsRg1qxZpn79+s7HzZo1MwsXLnTp96mnnjJdu3Y1xvxvxz1nzhzn8p07dxpJzr8Mhw0b5vJlbIwxkyZNMq1bt3Y+jo2NNc8//7xLm/Xr1xtfX1/nEZ4TJ04YPz8/5xGTgueeMWOGc52cnBzTqFEj8+yzzxpjCgeJoUOHuuw8LuXUqVNGktm+fbvLcxYXVC5V82+lpaUZh8PhDCa/9eabb5rw8HCTkZHhnPfJJ58YHx8fc/z4cWPMr+9zbGysyc3NdbYZPHiwGTJkiDHGmCVLlpjQ0NBi/xq/OKi407bAU089Zfr16+cy78iRI0aS2bNnj3O9a665xqVN586dzSOPPOJ8XNqjGAcPHjR79+4tdvrpp58u2YcxJQeVadOmmbVr15otW7aYGTNmGIfD4RLuivPwww+boKAgI8l06dLFGZgLJCYmmnr16hlfX18jyXTt2tXlaN+OHTtM9+7dTePGjc3QoUNNamqq+X//7/+ZG2+80fz000+mX79+plmzZubxxx8v1Wu8mDv7b8aoAKg0y5YtU61atRQQEKCBAwdqyJAhmjp1qnN5UFCQmjVr5nwcFRWlkydPSpIyMzO1f/9+3XvvvapVq5Zzevrpp7V//36X52nXrp1LH5Kc/ezevVsJCQku7RMSErR3717l5eUVW/tVV12lNm3aaP78+ZKkf//734qNjVX37t1d2nXt2tX5bz8/P3Xq1Em7d+8uss+kpCT17t272Ofcu3evhg4dqssuu0yhoaFq0qSJJOnw4cPFruNJzQV2796t7OzsYmvavXu32rdvr+DgYOe8hIQE5efna8+ePc55bdq0ka+vr/Pxxe9j3759FRsbq8suu0zDhw/XggULlJWVVeTzudO2wLZt27R69WqXz0jLli0lyeVzcvFn5Lc1uiM2NlZxcXHFTg0bNnS7z9968sknlZCQoPj4eD3yyCN6+OGHSzW2a9KkSdq6das+++wz+fr66q677pIxRpJ0/PhxjRo1SiNGjNDGjRu1Zs0a2e123Xrrrc42bdq00Zo1a3To0CEtXLhQOTk5mjJlil555RWNHz9e3bp107Zt2/T+++/r448/LvPrLA5BBUCl6dmzp5KSkrR3716dO3dO8+fPd9np+fv7u7S32WzOL82MjAxJ0uzZs5WUlOScduzYoe+++85lvYv7KRi4mp+fX+b6R44cqXnz5kn6dXDjPffcU6aBsYGBgSUuLzjTYvbs2Vq/fr3Wr18v6dcBmBVR86XqKa2i3seC7R8SEqItW7Zo0aJFioqK0l/+8he1b9++yFOq3WlbICMjQ9dff73LZ6TgM3dxQCupRne0adPGJRT9dho4cKDbfV7K1VdfrZ9++knZ2dkltouMjNTll1+uvn37avHixVq+fLnz/8qsWbMUFham5557TvHx8erevbv+/e9/a9WqVc7P2W9NnDhREyZMUKNGjZSYmKjBgwcrODhY1113nRITE8v7ZToRVABUmuDgYMXFxalx48by8/Nza9369esrOjpaycnJhf5qbdq0aan7adWqlb755huXed98840uv/xy51EAu91e5NGVO++8U4cOHdJLL72kXbt2acSIEYXaXByacnNztXnzZrVq1arIWtq1a6dVq1YVuezMmTPas2ePnnji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NGiQWbt2rTlw4IBJTEw0SUlJlVx59eDu9l+wYIFxOBxmwYIF5sCBA2blypUmKirKPPDAA5VcefWwfPly8/jjj5v333/fSDJLly4tsX1ycrIJCgoyEydONLt27TIvv/yy8fX1NStWrKjQOgkqMFdddZUZN26c83FeXp6Jjo4206dPL9X6ubm5JiQkxMyfP7+iSqzWPNn+ubm5plu3bmbOnDlmxIgRBBUPubvtX3vtNXPZZZeZCxcuVFaJ1Zq723/cuHGmV69eLvMmTpxoEhISKrTOmqA0QeXhhx82bdq0cZk3ZMgQ079//wqszBh++qnhLly4oM2bN6tPnz7OeT4+PurTp4/WrVtXqj6ysrKUk5OjiIiIiiqz2vJ0+0+bNk316tXTvffeWxllVkuebPuPPvpIXbt21bhx41S/fn21bdtWzzzzjPLy8iqr7GrDk+3frVs3bd682fnzUHJyspYvX65BgwZVSs013bp161zeL0nq379/qfcVnqrSNyVE2Z0+fVp5eXmqX7++y/z69evrhx9+KFUfjzzyiKKjowt9gHFpnmz/tWvX6q233lJSUlIlVFh9ebLtk5OT9eWXX+qOO+7Q8uXLtW/fPo0dO1Y5OTmaMmVKZZRdbXiy/YcNG6bTp0/rmmuukTFGubm5Gj16tB577LHKKLnGO378eJHvV1pams6dO6fAwMAKeV6OqKBMZsyYocWLF2vp0qUKCAjwdjnVXnp6uoYPH67Zs2crMjLS2+XUOPn5+apXr57efPNNdezYUUOGDNHjjz+u119/3dul1QiJiYl65pln9Oqrr2rLli16//339cknn+ipp57ydmmoQBxRqeEiIyPl6+urEydOuMw/ceKEGjRoUOK6f//73zVjxgx98cUXateuXUWWWW25u/3379+vgwcP6vrrr3fOy8/PlyT5+flpz549atasWcUWXU148tmPioqSv7+/fH19nfNatWql48eP68KFC7Lb7RVac3XiyfZ/8sknNXz4cI0cOVKSdMUVVygzM1N//OMf9fjjj8vHh7+9K1KDBg2KfL9CQ0Mr7GiKxBGVGs9ut6tjx45atWqVc15+fr5WrVqlrl27Frvec889p6eeekorVqxQp06dKqPUasnd7d+yZUtt375dSUlJzumGG25Qz549lZSUpJiYmMosv0rz5LOfkJCgffv2OcOhJP3444+KiooipLjJk+2flZVVKIwUhEbDbesqXNeuXV3eL0n6/PPPS9xXlIsKHaqLKmHx4sXG4XCYefPmmV27dpk//vGPpnbt2ub48ePGGGOGDx9uHn30UWf7GTNmGLvdbt577z1z7Ngx55Senu6tl1Clubv9f4uzfjzn7rY/fPiwCQkJMffdd5/Zs2ePWbZsmalXr555+umnvfUSqjR3t/+UKVNMSEiIWbRokUlOTjafffaZadasmbntttu89RKqtPT0dLN161azdetWI8n885//NFu3bjWHDh0yxhjz6KOPmuHDhzvbF5yePGnSJLN7924za9YsTk9G5Xn55ZdN48aNjd1uN1dddZX57rvvnMt69OhhRowY4XwcGxtrJBWapkyZUvmFVxPubP/fIqiUjbvb/ttvvzVXX321cTgc5rLLLjN/+9vfTG5ubiVXXX24s/1zcnLM1KlTTbNmzUxAQICJiYkxY8eONWfPnq38wquB1atXF/ldXrDNR4wYYXr06FFonQ4dOhi73W4uu+wyM3fu3Aqv02YMx8sAAIA1MUYFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFAABYFkEFgKX1799fvr6+2rhxY6Fld999t2w2m2w2m+x2u+Li4jRt2jTl5uZ6oVIAFYGgAsCyDh8+rG+//Vb33Xef3n777SLbDBgwQMeOHdPevXv14IMPaurUqZo5c2YlVwqgohBUAFS4a6+9VuPHj9eECRMUHh6u+vXra/bs2crMzNQ999yjkJAQxcXF6dNPP3VZb+7cufr973+vMWPGaNGiRTp37lyhvh0Ohxo0aKDY2FiNGTNGffr00UcffVRZLw1ABSOoAKgU8+fPV2RkpDZs2KDx48drzJgxGjx4sLp166YtW7aoX79+Gj58uLKysiRJxhjNnTtXd955p1q2bKm4uDi99957l3yewMBAXbhwoaJfDoBKQlABUCnat2+vJ554Qs2bN9fkyZMVEBCgyMhIjRo1Ss2bN9df/vIXnTlzRt9//70k6YsvvlBWVpb69+8vSbrzzjv11ltvFdu/MUZffPGFVq5cqV69elXKawJQ8QgqACpFu3btnP/29fVVnTp1dMUVVzjn1a9fX5J08uRJSdLbb7+tIUOGyM/PT5I0dOhQffPNN9q/f79Lv8uWLVOtWrUUEBCggQMHasiQIZo6dWoFvxoAlYWgAqBS+Pv7uzy22Wwu82w2myQpPz9fv/zyi5YuXapXX31Vfn5+8vPzU8OGDZWbm1toUG3Pnj2VlJSkvXv36ty5c5o/f76Cg4Mr/gUBqBR+3i4AAH5rwYIFatSokT744AOX+Z999pn+8Y9/aNq0afL19ZUkBQcHKy4uzgtVAqgMBBUAlvPWW2/p1ltvVdu2bV3mx8TEaPLkyVqxYoWuu+46L1UHoDLx0w8AS9m/f7+2bdumW265pdCysLAw9e7du8RBtQCqF5sxxni7CAAAgKJwRAUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFgWQQUAAFjW/wdjHVoMVQbXvwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "consistent_ratio = target_maps.below_corrected_p.mean()\n", + "\n", + "plt.scatter(\n", + " data=target_maps,\n", + " x=\"mean_average_precision\",\n", + " y=\"-log10(p-value)\",\n", + " c=\"below_corrected_p\",\n", + " cmap=\"tab10\",\n", + " s=10,\n", + ")\n", + "plt.xlabel(\"mAP\")\n", + "plt.ylabel(\"-log10(p-value)\")\n", + "plt.axhline(-np.log10(0.05), color=\"black\", linestyle=\"--\")\n", + "plt.text(\n", + " 0.5,\n", + " 1.5,\n", + " f\"Phenotypically consistent = {100 * consistent_ratio:.2f}%\",\n", + " va=\"center\",\n", + " ha=\"left\",\n", + ")\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can list compounds that are phenotypically active and consistent.\n", + "\n", + "Note that in multi-label scenario, when each compound can have multiple targets, the same compound can have \"consistent\" response in respect to one target, but not another." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Phenotypically consistent targets: DRD2, EGFR, HTR3A, PSMB1\n", + "Phenotypically consistent compounds: BRD-A69636825-003-04-7, BRD-K50691590-001-02-2, BRD-K60230970-001-10-0, BRD-K70330367-003-07-9, BRD-K70358946-001-15-7, BRD-K70401845-003-09-6, BRD-K70914287-300-02-8\n" + ] + } + ], + "source": [ + "consistent_targets = target_maps.query(\"below_corrected_p\")[\"Metadata_target\"]\n", + "consistent_compounds = df_active[\n", + " df_active[\"Metadata_target\"].apply(\n", + " lambda x: any(t in x for t in consistent_targets)\n", + " )\n", + "][\"Metadata_broad_sample\"]\n", + "\n", + "print(f\"Phenotypically consistent targets: {consistent_targets.str.cat(sep=', ')}\")\n", + "print(f\"Phenotypically consistent compounds: {consistent_compounds.str.cat(sep=', ')}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "copairs", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From bc49fd44fc2b0c43709d14a0f7f7d7702a187559 Mon Sep 17 00:00:00 2001 From: John Arevalo Date: Tue, 4 Feb 2025 10:41:01 -0500 Subject: [PATCH 16/21] using np.nonzero --- tests/test_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_map.py b/tests/test_map.py index 4beeaaf..1c69a4c 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -16,7 +16,7 @@ def binary2indices(arr: np.ndarray) -> np.ndarray: """Convert a binary matrix to a list of indices.""" - return np.where(arr == 1)[1].reshape(arr.shape[0], arr.sum(axis=1)[0]) + return np.nonzero(arr)[1].reshape(arr.shape[0], -1) def test_random_binary_matrix(): From f59536865d500fcc8f1c932ea372cd6f5540f137 Mon Sep 17 00:00:00 2001 From: John Arevalo Date: Tue, 4 Feb 2025 13:27:27 -0500 Subject: [PATCH 17/21] Add test for assign reference index function --- tests/test_reference_index.py | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/test_reference_index.py diff --git a/tests/test_reference_index.py b/tests/test_reference_index.py new file mode 100644 index 0000000..4854771 --- /dev/null +++ b/tests/test_reference_index.py @@ -0,0 +1,43 @@ +"""Tests for assign reference index helper function.""" + +import numpy as np +import pandas as pd + +from copairs.map import average_precision +from copairs.matching import assign_reference_index +from tests.helpers import simulate_random_dframe + + +def test_assign_reference_index(): + SEED = 42 + length = 20 + vocab_size = {"p": 5, "w": 3, "l": 4} + n_feats = 5 + pos_sameby = ["l"] + pos_diffby = [] + neg_sameby = [] + neg_diffby = ["l"] + rng = np.random.default_rng(SEED) + meta = simulate_random_dframe(length, vocab_size, pos_sameby, pos_diffby, rng) + length = len(meta) + feats = rng.uniform(size=(length, n_feats)) + + ap = average_precision(meta, feats, pos_sameby, pos_diffby, neg_sameby, neg_diffby) + + ap_ri = average_precision( + assign_reference_index(meta, "l=='l1'"), + feats, + pos_sameby + ["Metadata_Reference_Index"], + pos_diffby, + neg_sameby, + neg_diffby + ["Metadata_Reference_Index"], + ) + + # Check no AP values were computed for the reference samples. + assert ap_ri.query("l=='l1'").average_precision.isna().all() + + # Check AP values for all other samples are equal + pd.testing.assert_frame_equal( + ap_ri.query("l!='l1'").drop(columns="Metadata_Reference_Index"), + ap.query("l!='l1'"), + ).all(axis=None) From 0bb7b982e2bfb56bb43f9c1a14462e985e276b26 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Tue, 4 Feb 2025 18:25:08 -0500 Subject: [PATCH 18/21] fix(tests): limit ref column test to 2 labels --- tests/test_reference_index.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_reference_index.py b/tests/test_reference_index.py index 4854771..f6fb859 100644 --- a/tests/test_reference_index.py +++ b/tests/test_reference_index.py @@ -11,7 +11,7 @@ def test_assign_reference_index(): SEED = 42 length = 20 - vocab_size = {"p": 5, "w": 3, "l": 4} + vocab_size = {"p": 5, "w": 3, "l": 2} n_feats = 5 pos_sameby = ["l"] pos_diffby = [] @@ -40,4 +40,4 @@ def test_assign_reference_index(): pd.testing.assert_frame_equal( ap_ri.query("l!='l1'").drop(columns="Metadata_Reference_Index"), ap.query("l!='l1'"), - ).all(axis=None) + ) From c3aecb91aaa0a77f0efe9f38192ab370324149f3 Mon Sep 17 00:00:00 2001 From: alxndrkalinin <1107762+alxndrkalinin@users.noreply.github.com> Date: Tue, 4 Feb 2025 18:25:44 -0500 Subject: [PATCH 19/21] chore: gitignore vscode --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cd7f941..6e9b121 100644 --- a/.gitignore +++ b/.gitignore @@ -159,4 +159,5 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ -examples/data/ \ No newline at end of file +examples/data/ +.vscode/ \ No newline at end of file From b0f0129f7fdceb8dadca0c81622b4a96476affd3 Mon Sep 17 00:00:00 2001 From: John Arevalo Date: Wed, 5 Feb 2025 10:48:28 -0500 Subject: [PATCH 20/21] Update ref_index test --- src/copairs/compute.py | 6 +++--- src/copairs/map/map.py | 5 ++++- tests/test_reference_index.py | 12 +++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/copairs/compute.py b/src/copairs/compute.py index 2119fe7..7d25deb 100644 --- a/src/copairs/compute.py +++ b/src/copairs/compute.py @@ -2,7 +2,7 @@ import os from multiprocessing.pool import ThreadPool from pathlib import Path -from typing import Callable, Tuple, Optional, Union +from typing import Callable, Tuple, Union import numpy as np from tqdm.autonotebook import tqdm @@ -312,7 +312,7 @@ def average_precision(rel_k) -> np.ndarray: num_pos = rel_k.shape[1] pr_k = np.arange(1, num_pos + 1, dtype=np.float32) / (rel_k + 1) ap_values = pr_k.sum(axis=1) / num_pos - return ap_values + return ap_values.astype(np.float32) def ap_contiguous( @@ -399,7 +399,7 @@ def random_ap(num_perm: int, num_pos: int, total: int, seed: int): # Compute Average Precision (AP) scores for each row of the binary matrix null_dist = average_precision(rel_k) - return null_dist.astype(np.float32) + return null_dist def null_dist_cached( diff --git a/src/copairs/map/map.py b/src/copairs/map/map.py index 861e4e3..4dce123 100644 --- a/src/copairs/map/map.py +++ b/src/copairs/map/map.py @@ -1,4 +1,5 @@ import logging +from typing import Optional import numpy as np import pandas as pd @@ -16,7 +17,7 @@ def mean_average_precision( null_size: int, threshold: float, seed: int, - max_workers: int = 32, + max_workers: Optional[int] = None, ) -> pd.DataFrame: """Calculate the Mean Average Precision (mAP) score and associated p-values. @@ -38,6 +39,8 @@ def mean_average_precision( p-value threshold for identifying significant MaP scores. seed : int Random seed for reproducibility. + max_workers : int + Number of workers used. Default defined by tqdm's `thread_map` Returns: ------- diff --git a/tests/test_reference_index.py b/tests/test_reference_index.py index f6fb859..e57a02c 100644 --- a/tests/test_reference_index.py +++ b/tests/test_reference_index.py @@ -1,5 +1,6 @@ """Tests for assign reference index helper function.""" +import pytest import numpy as np import pandas as pd @@ -8,10 +9,11 @@ from tests.helpers import simulate_random_dframe +@pytest.mark.filterwarnings("ignore:invalid value encountered in divide") def test_assign_reference_index(): SEED = 42 - length = 20 - vocab_size = {"p": 5, "w": 3, "l": 2} + length = 200 + vocab_size = {"p": 5, "w": 3, "l": 4} n_feats = 5 pos_sameby = ["l"] pos_diffby = [] @@ -19,10 +21,14 @@ def test_assign_reference_index(): neg_diffby = ["l"] rng = np.random.default_rng(SEED) meta = simulate_random_dframe(length, vocab_size, pos_sameby, pos_diffby, rng) + # p: Plate, w: Well, l: PerturbationID, t: PerturbationType (is control?) + meta.eval("t=(l=='l1')", inplace=True) length = len(meta) feats = rng.uniform(size=(length, n_feats)) - ap = average_precision(meta, feats, pos_sameby, pos_diffby, neg_sameby, neg_diffby) + ap = average_precision( + meta, feats, pos_sameby + ["t"], pos_diffby, neg_sameby, neg_diffby + ["t"] + ) ap_ri = average_precision( assign_reference_index(meta, "l=='l1'"), From 716bea4456ada896c338d68912465962141028ac Mon Sep 17 00:00:00 2001 From: John Arevalo Date: Wed, 5 Feb 2025 14:21:43 -0500 Subject: [PATCH 21/21] Fix #71: Add docstring validation --- examples/null_size.ipynb | 2 +- pyproject.toml | 6 ++ src/copairs/__init__.py | 4 +- src/copairs/compute.py | 86 +++++++++++++++------------- src/copairs/map/__init__.py | 2 + src/copairs/map/average_precision.py | 23 ++++---- src/copairs/map/filter.py | 30 +++++----- src/copairs/map/map.py | 6 +- src/copairs/map/multilabel.py | 17 ++++-- src/copairs/matching.py | 62 ++++++++++---------- src/copairs/plot.py | 6 +- src/copairs/replicating.py | 69 +++++++++++----------- tests/test_reference_index.py | 1 + 13 files changed, 169 insertions(+), 145 deletions(-) diff --git a/examples/null_size.ipynb b/examples/null_size.ipynb index 87cc60c..b8e2061 100644 --- a/examples/null_size.ipynb +++ b/examples/null_size.ipynb @@ -36,7 +36,7 @@ " cmap=\"tab10\",\n", " figsize=(12, 6),\n", "):\n", - " \"\"\"Plots a grid of scatter plots for different values of a given column.\n", + " \"\"\"Plot a grid of scatter plots for different values of a given column.\n", "\n", " Args:\n", " data (pd.DataFrame): Input DataFrame containing the data.\n", diff --git a/pyproject.toml b/pyproject.toml index f11b0ce..92728a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,3 +33,9 @@ build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] where = ["src"] + +[tool.ruff.lint] +select = ["D"] + +[tool.ruff.lint.pydocstyle] +convention = "numpy" diff --git a/src/copairs/__init__.py b/src/copairs/__init__.py index ee93afd..9c27384 100644 --- a/src/copairs/__init__.py +++ b/src/copairs/__init__.py @@ -1,6 +1,4 @@ -""" -Package to create pairwise lists based on sameby and diffby criteria -""" +"""Package to create pairwise lists based on sameby and diffby criteria.""" from .matching import Matcher, MatcherMultilabel diff --git a/src/copairs/compute.py b/src/copairs/compute.py index 7d25deb..c03c1b5 100644 --- a/src/copairs/compute.py +++ b/src/copairs/compute.py @@ -1,3 +1,5 @@ +"""Functions to compute distances and ranks using numpy operations.""" + import itertools import os from multiprocessing.pool import ThreadPool @@ -15,7 +17,7 @@ def parallel_map(par_func: Callable[[int], None], items: np.ndarray) -> None: tracking via `tqdm`. It is particularly useful for batch operations that benefit from multithreading. - Parameters: + Parameters ---------- par_func : Callable A function to execute for each item. It should accept a single argument @@ -45,18 +47,20 @@ def parallel_map(par_func: Callable[[int], None], items: np.ndarray) -> None: def batch_processing( pairwise_op: Callable[[np.ndarray, np.ndarray], np.ndarray], ): - """Decorator for adding batch processing to pairwise operations. + """ + Add batch processing support to pairwise operations. - This function wraps a pairwise operation to process data in batches, enabling - efficient computation and multithreading when working with large datasets. + This decorator wraps a pairwise operation to process data in batches, + enabling efficient computation and multithreading when working with large + datasets. - Parameters: + Parameters ---------- pairwise_op : Callable A function that computes pairwise operations (e.g., similarity or distance) between two arrays of features. - Returns: + Returns ------- Callable A wrapped function that processes pairwise operations in batches. @@ -89,14 +93,14 @@ def par_func(i): def pairwise_corr(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: """Compute the Pearson correlation coefficient for paired rows of two matrices. - Parameters: + Parameters ---------- x_sample : np.ndarray A 2D array where each row represents a profile y_sample : np.ndarray A 2D array of the same shape as `x_sample`. - Returns: + Returns ------- np.ndarray A 1D array of Pearson correlation coefficients for each row pair in @@ -125,14 +129,14 @@ def pairwise_corr(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: def pairwise_cosine(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: """Compute cosine similarity for paired rows of two matrices. - Parameters: + Parameters ---------- x_sample : np.ndarray A 2D array where each row represents a profile. y_sample : np.ndarray A 2D array of the same shape as `x_sample`. - Returns: + Returns ------- np.ndarray A 1D array of cosine similarity scores for each row pair in `x_sample` and `y_sample`. @@ -149,14 +153,14 @@ def pairwise_cosine(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: def pairwise_abs_cosine(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: """Compute the absolute cosine similarity for paired rows of two matrices. - Parameters: + Parameters ---------- x_sample : np.ndarray A 2D array where each row represents a profile. y_sample : np.ndarray A 2D array of the same shape as `x_sample`. - Returns: + Returns ------- np.ndarray Absolute values of cosine similarity scores. @@ -168,14 +172,14 @@ def pairwise_euclidean(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray """ Compute the inverse Euclidean distance for paired rows of two matrices. - Parameters: + Parameters ---------- x_sample : np.ndarray A 2D array where each row represents a profile. y_sample : np.ndarray A 2D array of the same shape as `x_sample`. - Returns: + Returns ------- np.ndarray A 1D array of inverse Euclidean distance scores (scaled to range 0-1). @@ -188,14 +192,14 @@ def pairwise_euclidean(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray def pairwise_manhattan(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: """Compute the inverse Manhattan distance for paired rows of two matrices. - Parameters: + Parameters ---------- x_sample : np.ndarray A 2D array where each row represents a profile. y_sample : np.ndarray A 2D array of the same shape as `x_sample`. - Returns: + Returns ------- np.ndarray A 1D array of inverse Manhattan distance scores (scaled to range 0-1). @@ -207,14 +211,14 @@ def pairwise_manhattan(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray def pairwise_chebyshev(x_sample: np.ndarray, y_sample: np.ndarray) -> np.ndarray: """Compute the inverse Chebyshev distance for paired rows of two matrices. - Parameters: + Parameters ---------- x_sample : np.ndarray A 2D array where each row represents a profile. y_sample : np.ndarray A 2D array of the same shape as `x_sample`. - Returns: + Returns ------- np.ndarray A 1D array of inverse Chebyshev distance scores (scaled to range 0-1). @@ -230,7 +234,7 @@ def get_distance_fn(distance: Union[str, Callable]) -> Callable: for pairwise similarity or dissimilarity computations. Users can choose from a predefined set of metrics or provide a custom callable. - Parameters: + Parameters ---------- distance : str or callable The name of the distance metric or a custom callable function. Supported @@ -245,13 +249,13 @@ def get_distance_fn(distance: Union[str, Callable]) -> Callable: If a callable is provided, it must accept the paramters associated with each callable function. - Returns: + Returns ------- callable A function implementing the specified distance metric. - Raises: - ------- + Raises + ------ ValueError: If the provided `distance` is not a recognized string identifier or a valid callable. @@ -260,7 +264,6 @@ def get_distance_fn(distance: Union[str, Callable]) -> Callable: >>> distance_fn = get_distance_fn("cosine") >>> similarity_scores = distance_fn(x_sample, y_sample) """ - # Dictionary of supported distance metrics distance_metrics = { "abs_cosine": pairwise_abs_cosine, @@ -291,12 +294,13 @@ def get_distance_fn(distance: Union[str, Callable]) -> Callable: def random_binary_matrix(n, m, k, rng): """Generate a indices of k values in 1 per row in a random binary n*m matrix. + Args: n: Number of rows. m: Number of columns. k: Number of 1's per row. - Returns: + Returns ------- np.ndarray A binary matrix of shape `(n, m)` with exactly `k` ones per row. @@ -308,7 +312,7 @@ def random_binary_matrix(n, m, k, rng): def average_precision(rel_k) -> np.ndarray: - """Compute average precision based on binary list indices""" + """Compute average precision based on binary list indices.""" num_pos = rel_k.shape[1] pr_k = np.arange(1, num_pos + 1, dtype=np.float32) / (rel_k + 1) ap_values = pr_k.sum(axis=1) / num_pos @@ -324,7 +328,7 @@ def ap_contiguous( relevance labels and their associated counts. It also returns configurations indicating the number of positive and total pairs for each profile. - Parameters: + Parameters ---------- rel_k_list : np.ndarray Array of relevance labels (1 for positive pairs, 0 for negative pairs), sorted @@ -332,7 +336,7 @@ def ap_contiguous( counts : np.ndarray Array indicating how many times each profile appears in the rank list. - Returns: + Returns ------- ap_scores : np.ndarray Array of Average Precision scores for each profile. @@ -373,7 +377,7 @@ def random_ap(num_perm: int, num_pos: int, total: int, seed: int): generated binary relevance lists. It is useful for generating a null distribution to assess the significance of observed AP scores. - Parameters: + Parameters ---------- num_perm : int Number of random permutations (i.e., how many random relevance lists to generate). @@ -384,7 +388,7 @@ def random_ap(num_perm: int, num_pos: int, total: int, seed: int): seed : int Seed for the random number generator to ensure reproducibility. - Returns: + Returns ------- np.ndarray A 1D array containing the Average Precision scores for each randomly @@ -411,7 +415,7 @@ def null_dist_cached( pairs (`num_pos`) and total pairs (`total`). It uses caching to store and retrieve precomputed distributions, saving time and computational resources. - Parameters: + Parameters ---------- num_pos : int Number of positive pairs in the configuration. @@ -424,7 +428,7 @@ def null_dist_cached( cache_dir : Path Directory to store or retrieve cached null distributions. - Returns: + Returns ------- np.ndarray Null distribution for the specified configuration. @@ -453,7 +457,8 @@ def null_dist_cached( def get_null_dists(confs: np.ndarray, null_size: int, seed: int) -> np.ndarray: """Generate null distributions for each configuration of positive and total pairs. - Parameters: + + Parameters ---------- confs : np.ndarray Array where each row contains the number of positive pairs (`num_pos`) @@ -463,7 +468,7 @@ def get_null_dists(confs: np.ndarray, null_size: int, seed: int) -> np.ndarray: seed : int Random seed for reproducibility. - Returns: + Returns ------- np.ndarray A 2D array where each row corresponds to a null distribution for a specific @@ -493,10 +498,9 @@ def par_func(i): def p_values(ap_scores: np.ndarray, null_confs: np.ndarray, null_size: int, seed: int): - """Calculate p-values for an array of Average Precision (AP) scores - using a null distribution. + """Calculate p-values for an array of Average Precision (AP) scores using a null distribution. - Parameters: + Parameters ---------- ap_scores : np.ndarray Array of observed AP scores for which to calculate p-values. @@ -509,7 +513,7 @@ def p_values(ap_scores: np.ndarray, null_confs: np.ndarray, null_size: int, seed Seed for the random number generator to ensure reproducibility of the null distribution. - Returns: + Returns ------- np.ndarray An array of p-values corresponding to the input AP scores. @@ -544,14 +548,14 @@ def concat_ranges(start: np.ndarray, end: np.ndarray) -> np.ndarray: by the `start` and `end` arrays. Each range is inclusive of `start` and exclusive of `end`. - Parameters: + Parameters ---------- start : np.ndarray A 1D array of start indices for the ranges. end : np.ndarray A 1D array of end indices for the ranges. Must have the same shape as `start`. - Returns: + Returns ------- np.ndarray A 1D array containing the concatenated ranges. @@ -578,12 +582,12 @@ def to_cutoffs(counts: np.ndarray) -> np.ndarray: in a cumulative list. The first index is always `0`, and subsequent indices correspond to the cumulative sum of counts up to the previous entry. - Parameters: + Parameters ---------- counts : np.ndarray A 1D array of counts representing the size of each segment. - Returns: + Returns ------- np.ndarray A 1D array of cutoff indices where each value indicates the starting index diff --git a/src/copairs/map/__init__.py b/src/copairs/map/__init__.py index 0e1998c..f6c77c9 100644 --- a/src/copairs/map/__init__.py +++ b/src/copairs/map/__init__.py @@ -1,3 +1,5 @@ +"""Module to compute mAP-based metrics.""" + from . import multilabel from .average_precision import average_precision from .map import mean_average_precision diff --git a/src/copairs/map/average_precision.py b/src/copairs/map/average_precision.py index 8c7104e..8c73a35 100644 --- a/src/copairs/map/average_precision.py +++ b/src/copairs/map/average_precision.py @@ -1,9 +1,11 @@ +"""Functions to compute average precision.""" + import itertools import logging +from typing import List import numpy as np import pandas as pd -from typing import List from copairs import compute from copairs.matching import Matcher, UnpairedException @@ -24,7 +26,7 @@ def build_rank_lists( This function processes positive and negative pairs along with their similarity scores to construct rank lists and determine unique profile indices with their associated counts. - Parameters: + Parameters ---------- pos_pairs : np.ndarray Array of positive pair indices, where each pair is represented as a pair of integers. @@ -38,7 +40,7 @@ def build_rank_lists( neg_sims : np.ndarray Array of similarity scores for negative pairs. - Returns: + Returns ------- paired_ix : np.ndarray Unique indices of profiles that appear in the rank lists. @@ -50,7 +52,6 @@ def build_rank_lists( counts : np.ndarray Array of counts indicating how many times each profile index appears in the rank lists. """ - # Combine relevance labels: 1 for positive pairs, 0 for negative pairs labels = np.concatenate( [ @@ -91,15 +92,14 @@ def average_precision( batch_size: int = 20000, distance: str = "cosine", ) -> pd.DataFrame: - """Calculate average precision (AP) scores for pairs of profiles based on their - similarity. + """Calculate average precision (AP) scores for pairs of profiles based on their similarity. This function identifies positive and negative pairs of profiles using metadata rules, computes their similarity scores, and calculates average precision scores for each profile. The results include the number of positive and total pairs for each profile. - Parameters: + Parameters ---------- meta : pd.DataFrame Metadata of the profiles, including columns used for defining pairs. @@ -142,7 +142,7 @@ def average_precision( distance : str The distance metric used for computing similarities. Default is "cosine". - Returns: + Returns ------- pd.DataFrame A DataFrame containing the following columns: @@ -151,13 +151,13 @@ def average_precision( - 'n_total_pairs': The total number of pairs for each profile. - Additional metadata columns from the input. - Raises: + Raises ------ UnpairedException If no positive or negative pairs are found in the dataset. - Notes: - ------ + Notes + ----- - Positive Pair Rules: * Positive pairs are defined by `pos_sameby` (profiles share these metadata values) and optionally differentiated by `pos_diffby` (profiles must differ in these metadata values if specified). @@ -165,7 +165,6 @@ def average_precision( * Negative pairs are defined by `neg_diffby` (profiles differ in these metadata values) and optionally constrained by `neg_sameby` (profiles share these metadata values if specified). """ - # Combine all metadata columns needed for pair definitions columns = flatten_str_list(pos_sameby, pos_diffby, neg_sameby, neg_diffby) diff --git a/src/copairs/map/filter.py b/src/copairs/map/filter.py index c9603be..7106763 100644 --- a/src/copairs/map/filter.py +++ b/src/copairs/map/filter.py @@ -1,3 +1,5 @@ +"""Functions to support query-like syntax when finding the matches.""" + import itertools import re from typing import List, Tuple @@ -11,7 +13,7 @@ def validate_pipeline_input( ) -> None: """Validate the metadata and features for consistency and completeness. - Parameters: + Parameters ---------- meta : pd.DataFrame The metadata DataFrame describing the profiles. @@ -20,8 +22,8 @@ def validate_pipeline_input( columns : List[str] List of column names in the metadata to validate for null values. - Raises: - ------- + Raises + ------ ValueError: - If any of the specified metadata columns contain null values. - If the number of rows in the metadata and features are not equal. @@ -41,7 +43,7 @@ def validate_pipeline_input( def flatten_str_list(*args): - """create a single list with all the params given""" + """Create a single list with all the params given.""" columns = set() for col in args: if isinstance(col, str): @@ -63,14 +65,14 @@ def evaluate_and_filter( applies these conditions to the metadata DataFrame, and returns the filtered metadata along with the updated list of columns. - Parameters: + Parameters ---------- df : pd.DataFrame The metadata DataFrame containing information about profiles to be filtered. columns : List[str] A list of metadata column names. - Returns: + Returns ------- Tuple[pd.DataFrame, List[str]] - The filtered metadata DataFrame. @@ -91,7 +93,7 @@ def extract_filters( ) -> Tuple[List[str], List[str]]: """Extract and validate query filters from selected metadata columns. - Parameters: + Parameters ---------- columns : List[str] A list of selected metadata column names or query expressions. Query expressions @@ -99,14 +101,14 @@ def extract_filters( df_columns : List[str] All available metadata column names to validate against. - Returns: + Returns ------- Tuple[List[str], List[str]] - `queries_to_eval`: A list of valid query expressions to evaluate. - `parsed_cols`: A list of valid metadata column names extracted from the input `columns`. - Raises: - ------- + Raises + ------ ValueError: - If a metadata column or query expression is invalid (e.g., references a non-existent column). - If duplicate queries are found for the same metadata column. @@ -149,7 +151,7 @@ def apply_filters(df: pd.DataFrame, query_list: List[str]) -> pd.DataFrame: to filter its rows. If no query expressions are provided, the original DataFrame is returned unchanged. - Parameters: + Parameters ---------- df : pd.DataFrame The DataFrame to which the filters will be applied. @@ -157,13 +159,13 @@ def apply_filters(df: pd.DataFrame, query_list: List[str]) -> pd.DataFrame: A list of query expressions (e.g., "column_name > 5"). These expressions should follow the syntax supported by `pd.DataFrame.query`. - Returns: + Returns ------- pd.DataFrame The DataFrame filtered based on the provided query expressions. - Raises: - ------- + Raises + ------ ValueError: - If the combined query results in an empty DataFrame. - If the combined query expression is invalid. diff --git a/src/copairs/map/map.py b/src/copairs/map/map.py index 4dce123..66d4bbf 100644 --- a/src/copairs/map/map.py +++ b/src/copairs/map/map.py @@ -1,3 +1,5 @@ +"""Functions to compute mean average precision.""" + import logging from typing import Optional @@ -26,7 +28,7 @@ def mean_average_precision( scores by comparing them to a null distribution and performs multiple testing corrections. - Parameters: + Parameters ---------- ap_scores : pd.DataFrame DataFrame containing individual Average Precision (AP) scores and pair statistics @@ -42,7 +44,7 @@ def mean_average_precision( max_workers : int Number of workers used. Default defined by tqdm's `thread_map` - Returns: + Returns ------- pd.DataFrame DataFrame with the following columns: diff --git a/src/copairs/map/multilabel.py b/src/copairs/map/multilabel.py index 25ff6ff..8f17a0a 100644 --- a/src/copairs/map/multilabel.py +++ b/src/copairs/map/multilabel.py @@ -1,3 +1,5 @@ +"""Functions to compute mAP with multilabel support.""" + import itertools import logging @@ -12,7 +14,7 @@ logger = logging.getLogger("copairs") -def create_neg_query_solver(neg_pairs, neg_sims): +def _create_neg_query_solver(neg_pairs, neg_sims): # Melting and sorting by ix. neg_cutoffs splits the contiguous array neg_ix = neg_pairs.ravel() neg_sims = np.repeat(neg_sims, 2) @@ -35,7 +37,7 @@ def negs_for(query: np.ndarray): return negs_for -def build_rank_lists_multi(pos_pairs, pos_sims, pos_counts, negs_for): +def _build_rank_lists_multi(pos_pairs, pos_sims, pos_counts, negs_for): ap_scores_list, null_confs_list, ix_list = [], [], [] start = 0 @@ -76,6 +78,13 @@ def average_precision( batch_size=20000, distance="cosine", ) -> pd.DataFrame: + """ + Compute average precision with multilabel support. + + See Also + -------- + copairs.map.average_precision : Average precision without multilabel support. + """ columns = flatten_str_list(pos_sameby, pos_diffby, neg_sameby, neg_diffby) meta, columns = evaluate_and_filter(meta, columns) validate_pipeline_input(meta, feats, columns) @@ -120,8 +129,8 @@ def average_precision( neg_sims = distance_fn(feats, neg_pairs, batch_size) logger.info("Computing AP per label...") - negs_for = create_neg_query_solver(neg_pairs, neg_sims) - ap_scores_list, null_confs_list, ix_list = build_rank_lists_multi( + negs_for = _create_neg_query_solver(neg_pairs, neg_sims) + ap_scores_list, null_confs_list, ix_list = _build_rank_lists_multi( pos_pairs, pos_sims, pos_counts, negs_for ) diff --git a/src/copairs/matching.py b/src/copairs/matching.py index 26651c8..4095b56 100644 --- a/src/copairs/matching.py +++ b/src/copairs/matching.py @@ -1,6 +1,4 @@ -""" -Sample pairs with given column restrictions -""" +"""Sample pairs with given column restrictions.""" import itertools import logging @@ -25,7 +23,7 @@ def assign_reference_index( default_value: int = -1, inplace: bool = False, ): - """Assigns reference index to a specified column based on a given condition.""" + """Assign reference index to a specified column based on a given condition.""" if not inplace: df = df.copy() df[reference_col] = default_value @@ -36,12 +34,12 @@ def assign_reference_index( def reverse_index(col: pd.Series) -> pd.Series: - """Build a reverse_index for a given column in the DataFrame""" + """Build a reverse_index for a given column in the DataFrame.""" return pd.Series(col.groupby(col, observed=True).indices, name=col.name) def dict_to_dframe(dict_pairs, sameby: Union[str, list]): - """Convert the Matcher.get_all_pairs output to pd.DataFrame""" + """Convert the Matcher.get_all_pairs output to pd.DataFrame.""" if not dict_pairs: raise ValueError("dict_pairs empty") keys = np.array(list(dict_pairs.keys())) @@ -63,17 +61,14 @@ def dict_to_dframe(dict_pairs, sameby: Union[str, list]): class UnpairedException(Exception): - """Exception raised when a row can not be paired with any other row in the - data""" + """Exception raised when a row can not be paired with any other row in the data.""" class Matcher: - """Class to get pair of rows given contraints in the columns""" + """Class to get pair of rows given contraints in the columns.""" def __init__(self, dframe: pd.DataFrame, columns: ColumnList, seed: int): - """ - max_size: max number of rows to consider from the same value. - """ + """max_size: max number of rows to consider from the same value.""" rng = np.random.default_rng(seed) self.original_index = dframe.index dframe = dframe[columns].reset_index(drop=True).copy() @@ -102,9 +97,7 @@ def __init__(self, dframe: pd.DataFrame, columns: ColumnList, seed: int): self.rand_iter = iter([]) def _null_sample(self, diffby_all: ColumnList, diffby_any: ColumnList): - """ - Sample a pair from the frame. - """ + """Sample a pair from the frame.""" valid = set(self.frozen_valid) id1 = self.integers(0, len(valid) - 1) valid.remove(id1) @@ -118,7 +111,7 @@ def _null_sample(self, diffby_all: ColumnList, diffby_any: ColumnList): return id1, id2 def sample_null_pair(self, diffby: ColumnList, n_tries=5): - """Sample pairs from the data. It tries multiple times before raising an error""" + """Sample pairs from the data. It tries multiple times before raising an error.""" if isinstance(diffby, dict): diffby_all, diffby_any = diffby.get("all", []), diffby.get("any", []) if len(diffby_any) == 1: @@ -135,6 +128,7 @@ def sample_null_pair(self, diffby: ColumnList, n_tries=5): raise ValueError("Number of tries exhusted. Could not find a valid pair") def rand_next(self): + """Get next value from the precomputed value.""" try: value = next(self.rand_iter) except StopIteration: @@ -144,9 +138,11 @@ def rand_next(self): return value def integers(self, min_val, max_val): + """Get a random integer value between the specified range.""" return int(self.rand_next() * (max_val - min_val + 1) + min_val) def choice(self, items): + """Select a random item from the given list.""" min_val, max_val = 0, len(items) - 1 pos = self.integers(min_val, max_val) return items[pos] @@ -157,9 +153,7 @@ def get_all_pairs( diffby: Union[str, ColumnList, ColumnDict], original_index: bool = True, ): - """ - Get all pairs with given params - """ + """Get all pairs with given params.""" sameby, diffby = self._normalize_sameby_diffby(sameby, diffby) sameby, diffby = self._validate_inputs(sameby, diffby) @@ -185,9 +179,7 @@ def _get_original_index(self, pairs): } def _normalize_sameby_diffby(self, sameby, diffby): - """ - Convert sameby and diffby to a consistent format: {'all': [...], 'any': [...]} - """ + """Convert sameby and diffby to a consistent format: {'all': [...], 'any': [...]}.""" keys = ["all", "any"] result = [] @@ -311,8 +303,7 @@ def _get_all_pairs_single( return pairs def _only_diffby_all(self, diffby_all: ColumnList): - """Generate a dict with single NaN key containing all of the pairs - with different values in the column list""" + """Generate a dict with single NaN key containing all of the pairs with different values in the column list.""" diffby_all = sorted(diffby_all, key=self.col_order.get) # Cartesian product for one of the diffby columns @@ -328,8 +319,7 @@ def _only_diffby_all(self, diffby_all: ColumnList): return {None: list(map(tuple, pairs))} def _only_diffby_any(self, diffby: ColumnList): - """Generate a dict with single NaN key containing all of the pairs - with different values in any of specififed columns""" + """Generate a dict with single NaN key containing all of the pairs with different values in any of specififed columns.""" diffby = sorted(diffby, key=self.col_order.get) pairs = [] @@ -342,8 +332,7 @@ def _only_diffby_any(self, diffby: ColumnList): return {None: list(map(tuple, pairs))} def _only_diffby_all_any(self, diffby_all: ColumnList, diffby_any: ColumnList): - """Generate a dict with single NaN key containing all of the pairs - with different values in any of specififed columns""" + """Generate a dict with single NaN key containing all of the pairs with different values in any of specififed columns.""" diffby_all_pairs = np.asarray(self._only_diffby_all(diffby_all)[None]) diffby_all_any = self._filter_pairs_by_condition( diffby_all_pairs, diffby_any, condition="any_diff" @@ -354,12 +343,12 @@ def _filter_diffby( self, idx: int, diffby_all: ColumnList, diffby_any: ColumnList, valid: Set[int] ): """ - Remove from valid rows that have matches with idx in any of the diffby columns + Remove from valid rows that have matches with idx in any of the diffby columns. + :idx: index of the row to be compared :diffby: indices of columns that should have different values :valid: candidate rows to be evaluated - :returns: subset of valid after removing indices - + :returns: subset of valid after removing indices. """ row = self.values[idx] for col in diffby_all: @@ -405,6 +394,12 @@ def _filter_pairs_by_condition(self, pairs, columns, condition="all_same"): class MatcherMultilabel: + """ + Class to get pair of rows given contraints in the columns. + + Support one multilabel column. + """ + def __init__( self, dframe: pd.DataFrame, columns: ColumnList, multilabel_col: str, seed: int ): @@ -417,6 +412,7 @@ def __init__( self.matcher = Matcher(dframe, columns, seed) def get_all_pairs(self, sameby: Union[str, ColumnList], diffby: ColumnList): + """Get all pairs with given params.""" diffby_multi = self.multilabel_col in diffby if diffby_multi: # Multilabel in diffby must be 'ALL' instead of 'ANY' @@ -441,11 +437,13 @@ def get_all_pairs(self, sameby: Union[str, ColumnList], diffby: ColumnList): return pairs def sample_null_pair(self, diffby: ColumnList, n_tries=5): + """Sample pairs from the data. It tries multiple times before raising an error.""" null_pair = self.matcher.sample_null_pair(diffby, n_tries) id1, id2 = self.original_index[list(null_pair)].values return id1, id2 def get_null_pairs(self, diffby: ColumnList, size: int, n_tries=5): + """Sample multiple null pairs at the same time.""" null_pairs = [] for _ in tqdm(range(size)): null_pairs.append(self.matcher.sample_null_pair(diffby, n_tries)) @@ -455,7 +453,7 @@ def get_null_pairs(self, diffby: ColumnList, size: int, n_tries=5): return null_pairs def _only_diffby_multi(self): - """Special case when it is filter only by the diffby=multilabel_col""" + """Process special case when it is filter only by the diffby=multilabel_col.""" pairs = self.get_all_pairs(self.multilabel_col, []) pairs = itertools.chain.from_iterable(pairs.values()) pairs = set(map(frozenset, pairs)) diff --git a/src/copairs/plot.py b/src/copairs/plot.py index eea7010..903672f 100644 --- a/src/copairs/plot.py +++ b/src/copairs/plot.py @@ -1,3 +1,5 @@ +"""Functions to plot percent replicating.""" + from typing import Optional from plotly import graph_objects as go @@ -15,9 +17,7 @@ def plot( true_dist_title="True replicates", null_dist_title="Null distribution", ) -> go.Figure: - """ - Plot two distributions and threshold(s) line. - """ + """Plot two distributions and threshold(s) line.""" # fig = go.Figure() fig = make_subplots(specs=[[{"secondary_y": True}]]) diff --git a/src/copairs/replicating.py b/src/copairs/replicating.py index 3674f42..6fae6e4 100644 --- a/src/copairs/replicating.py +++ b/src/copairs/replicating.py @@ -1,4 +1,4 @@ -"""Class for getting Percent replicating metric""" +"""Class for getting Percent replicating metric.""" from typing import List, Literal @@ -29,15 +29,17 @@ def corr_between_non_replicates( ): """ Null distribution between random "replicates". - Parameters: - ------------ + + Parameters + ---------- df: pandas.DataFrame n_samples: int n_replicates: int diffby: list of columns that should be different use_rep: which data to use from .obsm property. `None` (default) uses `adata.X` - Returns: - -------- + + Returns + ------- list-like of correlation values, with a length of `n_samples` """ matcher = Matcher(meta, diffby, seed=0) @@ -49,13 +51,15 @@ def corr_between_non_replicates( def corr_from_pairs(X: np.ndarray, pairs: dict, sameby: List[str]): """ - Correlation from a list of named pairs. Generated by Matcher.get_all_pairs - Parameters: - ----------- + Correlation from a list of named pairs. Generated by Matcher.get_all_pairs. + + Parameters + ---------- X: Matrix containing samples in rows pairs: dictionary with list of index pairs. - Returns: - -------- + + Returns + ------- list-like of correlation values and median of number of replicates """ pair_ix = np.vstack(list(pairs.values())) @@ -92,15 +96,17 @@ def corr_between_replicates( X: np.ndarray, meta: pd.DataFrame, sameby: List[str], diffby: List[str] ): """ - Correlation between replicates - Parameters: - ----------- + Correlation between replicates. + + Parameters + ---------- adata: ad.AnnData sameby: Feature name to group the data frame by diffby: Feature name to force different values use_rep: which data to use from .obsm property. `None` (default) uses `adata.X` - Returns: - -------- + + Returns + ------- list-like of correlation values and median of number of replicates """ matcher = Matcher(meta, sameby + diffby, seed=0) @@ -109,18 +115,18 @@ def corr_between_replicates( class CorrelationTestResult: - """Class representing the percent replicating score. It stores distributions""" + """Class representing the percent replicating score. It stores distributions.""" def __init__(self, corr_df: pd.DataFrame, null_dist: pd.Series): - """Initialize object""" + """Initialize object.""" self.corr_df = corr_df self.corr_dist = corr_df["median"] self.null_dist = null_dist def percent_score_left(self): - """ - Calculates the percent score using the 5th percentile threshold. - :return: proportion of correlation distribution beyond the threshold and the threshold + """Calculate the percent score using the 5th percentile threshold. + + :return: proportion of correlation distribution beyond the threshold and the threshold. """ perc_5 = np.nanpercentile(self.null_dist, 5) below_threshold = self.corr_dist.dropna() < perc_5 @@ -128,8 +134,9 @@ def percent_score_left(self): def percent_score_right(self): """ - Calculates the percent score using the 95th percentile threshold. - :return: proportion of correlation distribution beyond the threshold and the threshold + Calculate the percent score using the 95th percentile threshold. + + :return: proportion of correlation distribution beyond the threshold and the threshold. """ perc_95 = np.nanpercentile(self.null_dist, 95) above_threshold = self.corr_dist.dropna() > perc_95 @@ -137,8 +144,9 @@ def percent_score_right(self): def percent_score_both(self): """ - Calculates the percent score using the 5th and 95th percentile or thresholds. - :return: proportion of correlation distribution beyond the thresholds and the thresholds + Calculate the percent score using the 5th and 95th percentile or thresholds. + + :return: proportion of correlation distribution beyond the thresholds and the thresholds. """ perc_95 = np.nanpercentile(self.null_dist, 95) above_threshold = self.corr_dist.dropna() > perc_95 @@ -154,6 +162,7 @@ def percent_score_both(self): ) def percent_score(self, how: Literal["left", "right", "both"]): + """Calculate percent score given the `how` criteria.""" left_th, right_th = None, None if how == "right": percent_score, right_th = self.percent_score_right() @@ -167,9 +176,7 @@ def percent_score(self, how: Literal["left", "right", "both"]): return percent_score, left_th, right_th def wasserstein_distance(self): - """ - Compute the Wasserstein distance between null and corr distributions. - """ + """Compute the Wasserstein distance between null and corr distributions.""" from scipy.stats import wasserstein_distance return wasserstein_distance(self.null_dist.values, self.corr_dist.values) @@ -182,9 +189,7 @@ def correlation_test( diffby: List[str], n_samples: int = 1000, ) -> CorrelationTestResult: - """ - Generate Null and replicate distribution for replicate correlation analysis - """ + """Generate Null and replicate distribution for replicate correlation analysis.""" corr_df, median_num_repl = corr_between_replicates(X, meta, sameby, diffby) n_replicates = min(median_num_repl, 50) @@ -202,9 +207,7 @@ def correlation_test( def correlation_test_from_pairs( X: np.ndarray, pairs: dict, null_pairs: list, sameby: list ) -> CorrelationTestResult: - """ - Generate Null and replicate distribution for replicate correlation analysis - """ + """Generate Null and replicate distribution for replicate correlation analysis.""" corr_df, median_num_repl = corr_from_pairs(X, pairs, sameby) n_replicates = min(median_num_repl, 50) null_dist = corr_from_null_pairs(X, null_pairs, n_replicates) diff --git a/tests/test_reference_index.py b/tests/test_reference_index.py index e57a02c..7820f75 100644 --- a/tests/test_reference_index.py +++ b/tests/test_reference_index.py @@ -11,6 +11,7 @@ @pytest.mark.filterwarnings("ignore:invalid value encountered in divide") def test_assign_reference_index(): + """Test ap values are not computed for ref samples.""" SEED = 42 length = 200 vocab_size = {"p": 5, "w": 3, "l": 4}