scanpy.pp.bbknn#
- scanpy.pp.bbknn(adata, neighbors_within_batch=3, n_pcs=None, *, batches='obs.batch', use=None, transformer=None, metric='euclidean', metric_kwds=mappingproxy({}), trim=None, rng=None, out=False)[source]#
Compute a batch balanced neighborhood graph of observations [Polański et al., 2019].
Batch balanced kNN alters the kNN procedure to identify each cell’s top neighbors in each batch separately instead of the entire cell pool with no accounting for batch. The nearest neighbors of each batch are then merged to create a final list of neighbors for the cell, which aligns batches in a quick and lightweight manner.
Use this as an alternative to
neighbors(): it writes the same fields, so all downstream steps (e.g.umap()orleiden()) work unchanged. This CPU implementation is based on the rapids-singlecell package.Array type support# Array type
supported
… experimentally in dask
Array✅
❌
✅
❌
- Parameters:
- adata
AnnData Annotated data matrix.
- neighbors_within_batch
int(default:3) How many top neighbors to report for each batch. The total number of neighbors is this number times the number of batches, which then serves as the basis for the construction of a symmetrical matrix of connectivities.
- n_pcs
int|None(default:None) Use this many PCs. If
n_pcs==0use.Xifuse is None.- batches
AdRef|str(default:'obs.batch') The annotation discriminating between the batches, e.g.
A.obs['batch'].strs areanndata.acc.AdAcc.resolve()d, e.g.'obs.batch'.- use
LayerAcc|MultiAcc|str|None(default:None) Use the indicated representation: a
LayerAcc(e.g.A.X,A.layers[...]) orMultiAcc(e.g.A.obsm[...]).strs areresolve()d, e.g.'obsm.pca'.If
None, the representation is chosen automatically: For.n_vars<N_PCS(default: 50),.Xis used, otherwise the PCA representation (.obsm['X_pca'], or.obsm['pca']if it was computed underScanpyV2Preview). If it is not present, it’s computed with default parameters orn_pcsif present.- transformer
KnnTransformerLike|Literal['pynndescent','sklearn'] |None(default:None) kNN search backend following the API of
KNeighborsTransformer. One index is built per batch and queried with all observations, so itsn_neighborsis ignored in favor ofneighbors_within_batch. See Using other kNN libraries in Scanpy for more details. Also accepts the following known options:None(the default)Behavior depends on data size. For small data, we will calculate exact kNN, otherwise we use
PyNNDescentTransformer'pynndescent'
- metric
Literal['cityblock','cosine','euclidean','l1','l2','manhattan'] |Literal['braycurtis','canberra','chebyshev','correlation','dice','hamming','jaccard','kulsinski','mahalanobis','minkowski','rogerstanimoto','russellrao','seuclidean','sokalmichener','sokalsneath','sqeuclidean','yule'] |Callable[[ndarray,ndarray],float] (default:'euclidean') A known metric’s name or a callable that returns a distance.
ignored if
transformeris an instance.- metric_kwds
Mapping[str,Any] (default:mappingproxy({})) Options for the metric.
ignored if
transformeris an instance.- trim
int|None(default:None) Trim each cell’s neighbors to these many top connectivities. May help with population independence and improve the tidiness of clustering. The lower the value, the more independent the individual populations, at the cost of a more conserved batch effect. If
None, this is set to 10 times the total number of neighbors. Set to 0 to skip trimming.- rng
int|integer|Sequence[int] |SeedSequence|Generator|BitGenerator|None(default:None) Random number generation to control stochasticity.
If a type:
SeedLikevalue, it’s used to seed a new random number generator; If anumpy.random.Generator,rng’s state will be directly advanced; IfNone, a non-reproducible random number generator is used. Seenumpy.random.default_rng()for more details.The default value matches legacy scanpy behavior and will change to
Nonein scanpy 2.0.ignored if
transformeris an instance.- out
GraphAcc|str|NeighborsOut|bool(default:False) Where to write the outputs. A single accessor writes
connectivitiesto it and names the others after its keyk:kin kinds of places no other output goes to, elsek_{name}, e.g..obsp['k_distances']next to.obsp['k']. Outputs that aren’t written by default stay unwritten. A mapping from output names to accessors writes only the outputs it names, each to a different place, e.g.{'connectivities': A.obsp['conns']}.strs areanndata.acc.AdAcc.resolve()d. Theunsentry is named afterconnectivities’s key, so a mapping has to includeconnectivities. IfTrue, they are returned as aNeighborsResultinstead of written. IfFalse, they are written to their default locations. The outputs are:connectivitiesThe weighted adjacency matrix. By default written to
A.obsp['connectivities'].distancesThe distance matrix. By default written to
A.obsp['distances'].
- adata
- Return type:
- Returns:
Returns the outputs if
out=True, elseNone. By default sets the following fields (seeoutfor others):adata.obsp['connectivities']scipy.sparse.csr_matrix(dtypefloat)Weighted adjacency matrix of the neighborhood graph of data points. Weights should be interpreted as connectivities.
adata.obsp['distances']scipy.sparse.csr_matrix(dtypefloat)Distance matrix of the batch balanced nearest neighbors search. Each row (cell) has
neighbors_within_batch×n_batches- 1 non-zero entries: its nearest neighbors in each batch, excluding the cell itself.adata.uns['neighbors']dictneighbors parameters, and the
.obspkeys the matrices were written to.
Examples
>>> import scanpy as sc >>> adata = sc.datasets.pbmc68k_reduced() >>> adata.obs["batch"] = adata.obs["phase"] >>> sc.pp.bbknn(adata, batches="obs.batch") >>> sc.tl.umap(adata)