Skip to content

Commit 7ee7bac

Browse files
authored
Merge branch 'main' into feature-cluster-decision-tree
2 parents e460214 + e0fc56a commit 7ee7bac

35 files changed

+175
-840
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.11.6
3+
rev: v0.11.8
44
hooks:
55
- id: ruff
66
args: ["--fix"]

benchmarks/benchmarks/preprocessing_log.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from typing import TYPE_CHECKING
99

1010
import scanpy as sc
11-
from scanpy.preprocessing._utils import _get_mean_var
1211

1312
from ._utils import get_dataset, param_skipper
1413

@@ -75,19 +74,3 @@ def time_scale(*_):
7574

7675
def peakmem_scale(*_):
7776
sc.pp.scale(adata, max_value=10)
78-
79-
80-
class FastSuite:
81-
"""Suite for fast preprocessing operations."""
82-
83-
params: tuple[list[Dataset], list[KeyX]] = (
84-
["pbmc3k", "pbmc68k_reduced", "bmmc", "lung93k"],
85-
[None, "off-axis"],
86-
)
87-
param_names = ("dataset", "layer")
88-
89-
def time_mean_var(self, *_):
90-
_get_mean_var(adata.X)
91-
92-
def peakmem_mean_var(self, *_):
93-
_get_mean_var(adata.X)

docs/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@
128128
cycler=("https://matplotlib.org/cycler/", None),
129129
dask=("https://docs.dask.org/en/stable/", None),
130130
dask_ml=("https://ml.dask.org/", None),
131+
fast_array_utils=(
132+
"https://icb-fast-array-utils.readthedocs-hosted.com/en/stable/",
133+
None,
134+
),
131135
h5py=("https://docs.h5py.org/en/stable/", None),
132136
zarr=("https://zarr.readthedocs.io/en/stable/", None),
133137
ipython=("https://ipython.readthedocs.io/en/stable/", None),

docs/release-notes/3598.dev.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Replaced several internal utilities with their {mod}`fast_array_utils` counterparts {smaller}`P Angerer`

docs/tutorials/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Tutorials
22

33
:::{seealso}
4-
For more tutorials featureing scanpy and other [scverse](https://scverse.org) ecosystem tools, check out the curated set of tutorials at [scverse.org/learn](https://scverse.org/learn)
4+
For more tutorials featuring scanpy and other [scverse](https://scverse.org) ecosystem tools, check out the curated set of tutorials at [scverse.org/learn](https://scverse.org/learn)
55
:::
66

77
## Basic workflows

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ classifiers = [
4848
dependencies = [
4949
"anndata>=0.9",
5050
"numpy>=1.25",
51+
"fast-array-utils[accel,sparse]>=1.2.1",
5152
"matplotlib>=3.7",
5253
"pandas >=2.0",
5354
"scipy>=1.11",
@@ -213,7 +214,7 @@ exclude_also = [
213214
"if __name__ == .__main__.:",
214215
"if TYPE_CHECKING:",
215216
# https://github.com/numba/numba/issues/4268
216-
'@(numba\.|nb\.)njit.*',
217+
'@(numba\.|nb\.)?njit.*',
217218
]
218219

219220
[tool.ruff]

src/scanpy/_utils/__init__.py

Lines changed: 3 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@
3434
from packaging.version import Version
3535

3636
from .. import logging as logg
37-
from .._compat import CSBase, DaskArray, _CSArray, _CSMatrix, pkg_version
37+
from .._compat import CSBase, DaskArray, _CSArray, pkg_version
3838
from .._settings import settings
39-
from .compute.is_constant import is_constant # noqa: F401
4039

4140
if Version(anndata_version) >= Version("0.10.0"):
4241
from anndata._core.sparse_dataset import (
@@ -53,7 +52,7 @@
5352

5453
from anndata import AnnData
5554
from igraph import Graph
56-
from numpy.typing import ArrayLike, DTypeLike, NDArray
55+
from numpy.typing import ArrayLike, NDArray
5756

5857
from .._compat import CSRBase
5958
from ..neighbors import NeighborsParams, RPForestDict
@@ -546,27 +545,6 @@ def get_literal_vals(typ: UnionType | Any) -> KeysView[Any]:
546545
# --------------------------------------------------------------------------------
547546

548547

549-
@singledispatch
550-
def elem_mul(x: _SupportedArray, y: _SupportedArray) -> _SupportedArray:
551-
raise NotImplementedError
552-
553-
554-
@elem_mul.register(np.ndarray)
555-
@elem_mul.register(CSBase)
556-
def _elem_mul_in_mem(x: _MemoryArray, y: _MemoryArray) -> _MemoryArray:
557-
if isinstance(x, CSBase):
558-
# returns coo_matrix, so cast back to input type
559-
return type(x)(x.multiply(y))
560-
return x * y
561-
562-
563-
@elem_mul.register(DaskArray)
564-
def _elem_mul_dask(x: DaskArray, y: DaskArray) -> DaskArray:
565-
import dask.array as da
566-
567-
return da.map_blocks(elem_mul, x, y)
568-
569-
570548
if TYPE_CHECKING:
571549
Scaling_T = TypeVar("Scaling_T", DaskArray, np.ndarray)
572550

@@ -606,7 +584,7 @@ def axis_mul_or_truediv(
606584
@axis_mul_or_truediv.register(CSBase)
607585
def _(
608586
X: CSBase,
609-
scaling_array,
587+
scaling_array: np.ndarray,
610588
axis: Literal[0, 1],
611589
op: Callable[[Any, Any], Any],
612590
*,
@@ -746,78 +724,6 @@ def _(X: DaskArray, axis: Literal[0, 1]) -> DaskArray:
746724
)
747725

748726

749-
@overload
750-
def axis_sum(
751-
X: _CSMatrix,
752-
*,
753-
axis: tuple[Literal[0, 1], ...] | Literal[0, 1] | None = None,
754-
dtype: DTypeLike | None = None,
755-
) -> np.matrix: ...
756-
757-
758-
@overload
759-
def axis_sum(
760-
X: np.ndarray, # TODO: or sparray
761-
*,
762-
axis: tuple[Literal[0, 1], ...] | Literal[0, 1] | None = None,
763-
dtype: DTypeLike | None = None,
764-
) -> np.ndarray: ...
765-
766-
767-
@singledispatch
768-
def axis_sum(
769-
X: np.ndarray | CSBase,
770-
*,
771-
axis: tuple[Literal[0, 1], ...] | Literal[0, 1] | None = None,
772-
dtype: DTypeLike | None = None,
773-
) -> np.ndarray | np.matrix:
774-
return np.sum(X, axis=axis, dtype=dtype)
775-
776-
777-
@axis_sum.register(DaskArray)
778-
def _(
779-
X: DaskArray,
780-
*,
781-
axis: tuple[Literal[0, 1], ...] | Literal[0, 1] | None = None,
782-
dtype: DTypeLike | None = None,
783-
) -> DaskArray:
784-
import dask.array as da
785-
786-
if dtype is None:
787-
dtype = getattr(np.zeros(1, dtype=X.dtype).sum(), "dtype", object)
788-
789-
if isinstance(X._meta, np.ndarray) and not isinstance(X._meta, np.matrix):
790-
return X.sum(axis=axis, dtype=dtype)
791-
792-
def sum_drop_keepdims(*args, **kwargs):
793-
kwargs.pop("computing_meta", None)
794-
# masked operations on sparse produce which numpy matrices gives the same API issues handled here
795-
if isinstance(X._meta, _CSMatrix | np.matrix) or isinstance(
796-
args[0], _CSMatrix | np.matrix
797-
):
798-
kwargs.pop("keepdims", None)
799-
axis = kwargs["axis"]
800-
if isinstance(axis, tuple):
801-
if len(axis) != 1:
802-
msg = f"`axis_sum` can only sum over one axis when `axis` arg is provided but got {axis} instead"
803-
raise ValueError(msg)
804-
kwargs["axis"] = axis[0]
805-
# returns a np.matrix normally, which is undesireable
806-
return np.array(np.sum(*args, dtype=dtype, **kwargs))
807-
808-
def aggregate_sum(*args, **kwargs):
809-
return np.sum(args[0], dtype=dtype, **kwargs)
810-
811-
return da.reduction(
812-
X,
813-
sum_drop_keepdims,
814-
aggregate_sum,
815-
axis=axis,
816-
dtype=dtype,
817-
meta=np.array([], dtype=dtype),
818-
)
819-
820-
821727
@singledispatch
822728
def check_nonnegative_integers(X: _SupportedArray) -> bool | DaskArray:
823729
"""Check values of X to ensure it is count data."""

src/scanpy/_utils/compute/__init__.py

Whitespace-only changes.

src/scanpy/_utils/compute/is_constant.py

Lines changed: 0 additions & 155 deletions
This file was deleted.

0 commit comments

Comments
 (0)